2

I am trying to get the work week number from a timestamp according to this system:

USA, Canada, most of Latin America, Japan, Israel, South Korea, among others, use a week numbering system (called North American in our Calculator) in which the first week (numbered 1) of any given year is the week which contains January 1st. The first day of a week is Sunday and Saturday is the last.

https://www.calendar-12.com/week_number

Python's strftime method supports %U and %W, but neither of these match that system. Pandas also adds %V following ISO 8601 but this is not what is used in North America either.

pyjamas
  • 4,608
  • 5
  • 38
  • 70
  • Could you explain how the given options are not working for you? How are they different? – Ralf Apr 12 '19 at 19:48
  • Also, take a look at this similar question https://stackoverflow.com/q/2600775/9225671 – Ralf Apr 12 '19 at 19:48
  • @Ralf That question asks about and has answers for week number according to ISO 8601, which as I mentioned in my question is not the standard in North America. As for how the builtin Python options are different, you can read their description here: http://strftime.org/. They just don't match the description in my question. I tried them all and compared, here's an example (2016/01/02 should be WW01): https://www.screencast.com/t/5lSOb7NRmsG – pyjamas Apr 12 '19 at 19:55
  • So basically what you want to achieve is the values returned by the `%U` option but incremented by 1 (so that the year starts at 1 instead of 0), is that correct? – Ralf Apr 12 '19 at 19:59
  • @Ralf I tried that but it's still incorrect. Increment by 1 is the first step, but then you still have this issue: https://www.screencast.com/t/5r4jttvh (those should all be the same week). So I then have to replace 53 with 1. Then I found some years ended up with the final week being 54, so I instead had to do a replacement on the maximum within the previous year. And even after all that I found that `%U` starts at 1 for some years like 2017, so initially incrementing by 1 makes that whole year wrong... – pyjamas Apr 13 '19 at 00:55

2 Answers2

1

Ok here's what I came up with... it would be nice if this was included in datetime or Pandas though

def US_week(ts):
    if pd.isnull(ts):
        return np.nan

    import datetime as dt
    U = int(ts.strftime('%U'))


    # If this is last week of year and next year starts with week 0, make this part of the next years first week
    if U == int(dt.datetime(ts.year, 12, 31).strftime('%U')) and int(
            dt.datetime(ts.year + 1, 1, 1).strftime('%U')) == 0:
        week = 1

    # Some years start with 1 not 0 (for example 2017), then U corresponds to the North American work week already
    elif int(dt.datetime(ts.year, 1, 1).strftime('%U')) == 1:
        week = U
    else:
        week = U + 1

    return week

def US_week_str(ts):
    week = US_week_str(ts)
    return "{}-{:02}".format(ts.year, week)
pyjamas
  • 4,608
  • 5
  • 38
  • 70
1

The following is the code I used in one of my projects. It is based on North American week numbering system where the first week is the week that contains January 1st.

from datetime import date

def week1_start_ordinal(year):
    jan1 = date(year, 1, 1)
    jan1_ordinal = jan1.toordinal()
    jan1_weekday = jan1.weekday()
    week1_start_ordinal = jan1_ordinal - ((jan1_weekday + 1) % 7)
    return week1_start_ordinal

def week_from_date(date_object):
    date_ordinal = date_object.toordinal()
    year = date_object.year
    week = ((date_ordinal - week1_start_ordinal(year)) // 7) + 1
    if week >= 52:
        if date_ordinal >= week1_start_ordinal(year + 1):
            year += 1
            week = 1
    return year, week

For example:

>>> from datetime import date
>>> week_from_date(date(2015, 12, 27))
(2016, 1)
mohd4482
  • 1,788
  • 14
  • 25