fiscalyear icon indicating copy to clipboard operation
fiscalyear copied to clipboard

Support for week number of a date in a FiscalYear

Open aravinds502 opened this issue 5 years ago • 20 comments

Is there any way to get the Week number for given date in a fiscal year or any plans to support this API?

Ex: import fiscalyear fiscalyear.START_MONTH = 7 fiscalyear.START_DAY = 1 cur_date = fiscalyear.FiscalDate(2019, 7, 1) print(cur_date.week) -> should give 1

aravinds502 avatar Jan 14 '20 06:01 aravinds502

@aravinds502 there is currently no way to do this (aside from manually calculating it), but I think that would be a great addition. We already have cur_date.fiscal_year and cur_date.fiscal_quarter, and I can definitely see a use in having cur_date.fiscal_month, cur_date.fiscal_week, and cur_date.fiscal_day. The real question is if we also want FiscalMonth, FiscalWeek, and FiscalDay objects.

If you would like to take a stab at implementing this, PRs are always welcome. Otherwise, if there's enough demand, I can take a look at this when I get a chance.

adamjstewart avatar Jan 14 '20 19:01 adamjstewart

Note that #11 adds a cur_date.fiscal_month attribute.

adamjstewart avatar Oct 15 '20 17:10 adamjstewart

@adamjstewart if there were a FiscalMonth class (for example), would you expect it to have year and month properties that returned the calendar year and month like the example below? So for a fiscal year that starts prior year, October:

>>> f = FiscalMonth(2020,1)
>>> f.month
10
>>> f.year
2019

Translating back from fiscal year and month to date is, naturally, my project's next requirement.

nicmendoza avatar Oct 16 '20 13:10 nicmendoza

I would expect FiscalMonth to be almost identical to FiscalYear. In order to avoid confusion, I would name the attributes fiscal_year and fiscal_month. I didn't do this for FiscalQuarter because Python's builtin datetime objects don't have a quarter attribute, although we can consider renaming it to fiscal_quarter if you think that would be more consistent.

adamjstewart avatar Oct 16 '20 16:10 adamjstewart

Got it, so for my use case (where I'm actually specifically interested in getting the calendar month and year back out from a FiscalMonth) it would look like this, right?:

>>> f = FiscalMonth(2020,1)
>>> f.start.month
10
>>> f.start.year
2019

nicmendoza avatar Oct 16 '20 16:10 nicmendoza

Yep, that looks correct.

adamjstewart avatar Oct 16 '20 16:10 adamjstewart

Hey @adamjstewart, hopefully continuing the conversation here makes sense. Plus I think eventually someone could readily build the original .fiscal_week request from this issue based on FiscalDay.

The definition of a "fiscal day" seems a little less universally-defined from my limited research, but would you expect Fiscal Day to work like the following? This is basically what I need for my own use case so I thought it could potentially fit into the fiscalyear library:

>>> f = FiscalDay(2020,1)
>>> f.year
2019
>>> f.month
10
>>>f.day
1
>>>f.fiscal_year
2020
>>>f.fiscal_quarter
1
>>>f.fiscal_month
1

And then right on up to >>> FiscalDay(2020,364)

Or something else?

nicmendoza avatar Dec 10 '20 21:12 nicmendoza

I think that API makes sense. I'm trying to think about the easiest way to implement this feature (and other features). Since the start of the fiscal year is a well defined point in time, we could simply use FiscalYear(year) + datetime.timedelta(days=days) to calculate it.

adamjstewart avatar Dec 11 '20 20:12 adamjstewart

Opened #13 for FiscalDay and fiscal_day.

nicmendoza avatar Dec 11 '20 23:12 nicmendoza

I calculate the week number in the Fiscal Quarter in a separate function and combine it with Fiscal quarter, but native support would be fantastic.

NEXT_MONDAY = relativedelta.relativedelta(weekday=relativedelta.MO)
LAST_MONDAY = relativedelta.relativedelta(weekday=relativedelta.MO(-1))
ONE_WEEK = timedelta(weeks=1)

def get_week_in_quarter(dt):
    d: date = dt.date()
    year = d.year

    # Q0 = January 1, Q1 = April 1, Q2 = July 1, Q3 = October 1
    quarter = ((d.month - 1) // 3)
    quarter_start = date(year, (quarter * 3) + 1, 1)
    quarter_week_2_monday = quarter_start + NEXT_MONDAY

    if d < quarter_week_2_monday:
        week = 1
    else:
        cur_week_monday = d + LAST_MONDAY
        week = int((cur_week_monday - quarter_week_2_monday) / ONE_WEEK) + 2

    if quarter == 0:
        year -= 1
        quarter = 4

    return week

Happy to add this properly when the FiscalDay PR is merged if there's interest. @aravinds502 This should work for you in the interim.

davedavis avatar Dec 17 '20 23:12 davedavis

The FiscalDay and fiscal_day PR has been merged, feel free to submit a PR for FiscalWeek and fiscal_week.

adamjstewart avatar Dec 18 '20 01:12 adamjstewart

Okay, support for fiscal months and days is merged and documented. Would anyone like to submit a PR to add fiscal weeks, or should I cut a new release at this point?

adamjstewart avatar Dec 19 '20 17:12 adamjstewart

@adamjstewart ready to release?

nicmendoza avatar Jan 14 '21 22:01 nicmendoza

Yeah, I can cut a new release if no one wants to work on fiscal week at the moment.

adamjstewart avatar Jan 14 '21 22:01 adamjstewart

Didn't see anything from @davedavis on this, so I put together a quick PR (#17) to cover the original request in this Issue. If anyone thinks of any missing test cases, please let me know.

nicmendoza avatar Feb 04 '21 18:02 nicmendoza

@aravinds502 @davedavis how do you define week number? Is it the number of weeks since the start of the fiscal year, or do you also need to consider the days of the week? For example, if the fiscal year starts on a Monday, and you consider weeks to go from Monday to Sunday, then both definitions are equal, but if the fiscal year starts in the middle of a week, would you add 1 to the week count?

adamjstewart avatar Feb 04 '21 19:02 adamjstewart

In support of @adamjstewart 's question, I found this example US fiscal calendar (although it notably doesn't have week numbers on it unlike 4-4-5 calendars I've sen) which standardizes on a Sunday-Saturday week without being a 4-4-5 calendar. Helpful for the visually oriented.

Aside from the central point Adam has raised here, it does beg the question of how to best handle the contains logic for checking if a week is in a month, since a week can straddle two. Relevant question regardless of which approach we take.

nicmendoza avatar Feb 04 '21 20:02 nicmendoza

Sorry guys, got swamped with another PR so unable to do this. So thanks @nicmendoza for going ahead.

@adamjstewart I just used relativedelta from dateutil. My requirement is basically that the first week in each quarter is quarter week 1. From the first day of Q1 is the same, but fiscal week 1. Each quarter quarter week resets but fiscal week doesn't.

This is not how other organizations do it so I wasn't going to mess around.

davedavis avatar Feb 04 '21 20:02 davedavis

I looked to see if there is a standard for counting weeks and it looks like ISO has one: https://en.wikipedia.org/wiki/ISO_week_date

Weeks start with Monday. Each week's year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January. ISO week year numbering therefore usually deviates by 1 from the Gregorian for some days close to 1 January.

I think we should stick to ISO whenever possible. Any objections?

adamjstewart avatar Feb 05 '21 20:02 adamjstewart

Excel also follows ISO 8601, although it's not the default behavior of their weeknum function. I guess because the default follows normal-people calendar conventions. No objections to following ISO 8601 in principle.

What I haven't wrapped my head around is how to butt this up against the current implementation of fiscalyear. The first day of the year won't necessarily line up to October 1 or April 6 most year. Would FiscalYear(2016,1) have a different start date than FiscalWeek(2016,1)?

Poking around for examples in the wild a bit, I came across Zap BI. I've never heard of them but they seem to talk a bit about their approach to this

Tableau's docs seem to gloss over it.

Lots of conversations online about how to get Excel to spit out a fiscal week

Also this: https://pypi.org/project/isoweek/

nicmendoza avatar Feb 05 '21 22:02 nicmendoza