From: Dan White Date: Thu, 6 Mar 2025 16:54:17 +0000 (-0600) Subject: TimeSampleHistogram: handle relative weeks X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=7a5f698b4d933d737cf61f8dfadc6728b2d96ab1;p=pubbin.git TimeSampleHistogram: handle relative weeks --- diff --git a/TimeSampleHistogram b/TimeSampleHistogram index 4289a5c..7945091 100755 --- a/TimeSampleHistogram +++ b/TimeSampleHistogram @@ -75,18 +75,6 @@ if not args: #opt.today = True #testing -# these are from -# http://stackoverflow.com/questions/304256/whats-the-best-way-to-find-the-inverse-of-datetime-isocalendar/1700069#1700069 -def iso_year_start(iso_year): - "The gregorian calendar date of the first day of the given ISO year" - fourth_jan = dt.date(iso_year, 1, 4) - delta = dt.timedelta(fourth_jan.isoweekday()-1) - return fourth_jan - delta - -def iso_to_gregorian(iso_year, iso_week, iso_day): - "Gregorian calendar date for the given ISO year, week and day" - year_start = iso_year_start(iso_year) - return year_start + dt.timedelta(iso_day-1, 0, 0, 0, 0, 0, iso_week-1) # # Date range filter @@ -124,31 +112,49 @@ if opt.days > 0: elif opt.days < 0: startdate = enddate + dt.timedelta(opt.days) -if opt.isoweek: + +if args.isoweek: + ## Formats accepted: + # 3 week 3 of this year + # 2025-09 week 3 of 2025 + # 1..4 range including weeks 1 through 4 + # + ### Nonstandard forms: + # 0 (this week) + # -1 (last week) + # +1 (next week) + # -3..-2 range including 3 weeks ago through 2 weeks ago + # any number of periods denote a range of weeks - wrange = opt.isoweek.replace('.', ' ').split() + wrange = args.isoweek.replace('.', ' ').split() # may be one or two items # if only one list item, then the second needs to be a copy of the first + # if there are already two items, then the added third one is unused wrange.append(wrange[0]) def wstr_to_date(wstr): - *year, week = wstr.split('-') - - if year: - year = int(year[0]) + now_dt = dt.datetime.now() + year = now_dt.year + # handle relative weeks first + if wstr[0] in ('+', '-') or wstr == '0': + woffset = int(wstr) + x = now_dt + dt.timedelta(weeks=woffset) + year, week, _ = x.isocalendar() else: - year = dt.datetime.now().year - - week = int(week) + *year, week = wstr.split('-') + week = int(week) + if year: # it was provided + year = int(year[0]) + else: # only week number provided, assume this year + year, *_ = now_dt.isocalendar() return (year, week) year, week = wstr_to_date(wrange[0]) - startdate = iso_to_gregorian(year, week, 1) + startdate = dt.date.fromisocalendar(year, week, 1) year, week = wstr_to_date(wrange[1]) - enddate = iso_to_gregorian(year, week, 7) - + enddate = dt.date.fromisocalendar(year, week, 7) # modify to include all of enddate instead of start-of-day