Given an time in seconds from Epoch, is there an algorithm that can convert the time to the week of the year?
CodePudding user response:
Absolutely, but it gets very complicated.
In principle you should be able to divide by 60*60*24 = 86400
to get days, then follow the logic of the calendar to figure out days, weeks, years, and calculate the answer from that. There are 365 days in a year, except leap years. Leap years occur on years divisible by 4, except ones divisible by 100, but happen again on years divisible by 400. Since 2000 is divisible by 400, you can ignore the last 2 rules and you will be correct until the year 2100.
You also have to decide what a week is defined as. In the USA it is traditionally defined as Sunday through Saturday. In Europe it is traditionally defined as Monday through Sunday. But you know what day of the week 1970 started on (Thursday), and can therefore figure out the current year, what day of the week it started on, when that week started, and a little modulo 7 arithmetic gives you your answer.
That is...until you notice that actual date boundaries depend on timezone, whether daylight savings time is in effect, and other such things. This opens up a giant can of worms that everyone delegates to the Olson database. (Which itself needs multiple updates a year because some government, somewhere, tweaks their timezone rules.) And then every language and environment wraps their own date-time library around that. You are strongly advised to find and use that.
If time is represented in UTC, this is the end of the story. However in fact we also have leap seconds (27 so far, possibly a negative one coming soon). This is NOT dealt with by Olson or standard date-time libraries. All of whom try to find the most efficient way to ignore that the leap second happened, and pray that they don't crash when the next one comes. (Not a joke. Linux servers around the world crashed on Jul 2, 2012, and large companies have a variety of "time smearing" approaches to avoid it happening again.)
Only specialized tools like Frink deal with the ugliness of leap seconds in their full glory.
CodePudding user response:
Assuming you already have the year, month, and day, here is the solution according to Pandas.
doy = get_day_of_year(year, month, day)
dow = dayofweek(year, month, day)
# estimate
iso_week = (doy - 1) - dow 3
if iso_week >= 0:
iso_week = iso_week // 7 1
# verify
if iso_week < 0:
if (iso_week > -2) or (iso_week == -2 and is_leapyear(year - 1)):
iso_week = 53
else:
iso_week = 52
elif iso_week == 53:
if 31 - day dow < 3:
iso_week = 1