Coder Social home page Coder Social logo

fiscalyear's People

Contributors

adamjstewart avatar curtlh avatar further-reading avatar nicmendoza avatar pmav99 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

fiscalyear's Issues

FiscalCalendar starting on 31st day of the month throws ValueError

If the FiscalCalendar starts on the 31st of any month with 31 days, then FiscalDate().quarter throws a ValueError.

Example code:

from fiscalyear import FiscalDate, FiscalYear, fiscal_calendar

with fiscal_calendar(start_month=12, start_day=31):
    fiscal_date = FiscalDate(2019, 10, 22)
    fiscal_date.quarter

Traceback:

Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "/site-packages/fiscalyear.py", line 594, in quarter
    if self in q:
  File "/site-packages/fiscalyear.py", line 413, in __contains__
    return self.start.date() <= item <= self.end.date()
  File "/site-packages/fiscalyear.py", line 493, in end
    next_start = self.next_quarter.start
  File "/site-packages/fiscalyear.py", line 485, in start
    return FiscalDateTime(year, month, START_DAY, 0, 0, 0)
ValueError: day is out of range for month

The quarters generated are:

  • December 31st
  • March 31st
  • June 31st โ† Not a valid day, so it breaks.

Make it possible to use multiple calendar settings in the same app.

My current usecase does not fall in this category, but a relatively subtle implication of the current implementation is that it is not really possible to use different fiscal calendar settings in the same application. The problem is that as soon as you update the global settings, the behaviour of the existing objects changes too. For example:

In [2]: from fiscalyear import *

In [3]: y = FiscalYear(2018)

In [4]: y.start
Out[4]: FiscalDateTime(2017, 10, 1, 0, 0)

In [5]: setup_fiscal_calendar('same', 1, 1)

In [6]: y.start
Out[6]: FiscalDateTime(2018, 1, 1, 0, 0)

Arguably, someone could claim that this is a feature too! :P
And in certain contexts, it probably is! Neverheless, it can also lead to subtle bugs and various errors when you do calculations. If nothing else, I think that there should be at least a warning in the docs.

PS. The older I get the more I like immutable objects :P

Add a function for easily changing the global "START_*" parameters

I think it would make sense to have a function that would make changing the global parameters easier. E.g.

def setup_fiscal_year(start_year, start_month, start_day):
    global START_YEAR, START_MONTH, START_DAY
    START_YEAR = start_year
    START_MONTH = start_month
    START_DAY = start_day

def test_setup_fiscal_year():
    # test defaults
    day =  fiscalyear.FiscalDate(2017, 12, 1)
    assert day.fiscal_year == 2018
    assert day.quarter == 1

    # change fiscal year settings
    fiscalyear.setup_fiscal_year("same", 1, 1)
    assert day.fiscal_year == 2017
    assert day.quarter == 4

    # restore defaults and re-test
    fiscalyear.setup_fiscal_year("previous", 10, 1)
    assert day.fiscal_year == 2018
    assert day.quarter == 1

This could also make it possible to change the Fiscal Year settings even if you don't import the whole module. E.g.

In [4]: from fiscalyear import FiscalQuarter, setup_fiscal_year

In [5]: quarter = FiscalQuarter(2018, 1)

In [6]: quarter.start
Out[6]: FiscalDateTime(2017, 10, 1, 0, 0)

In [7]: setup_fiscal_year('same', 1, 1)

In [8]: quarter.start
Out[8]: FiscalDateTime(2018, 1, 1, 0, 0)

FY=2022 for US 2021 calendar year

Hello, If my assumption is correct, I was expecting the lib to return fiscal_year=2021 when the calendar is set to start on January to follow the calendar year, since the end date (2021-12-31) still falls in 2021.

Code to reproduce:

import fiscalyear
import datetime

start_month = 1
sdate = datetime.datetime(2021, 1, 1)

with fiscalyear.fiscal_calendar(start_day=1, start_month=start_month, start_year='previous'):
  f = fiscalyear.FiscalDate(sdate.year, sdate.month, sdate.day)
  print('ISO:', f.isoformat(), ' FY:',  f.fiscal_year, ' FQ:', f.fiscal_quarter, ' FM:', f.fiscal_month)
  fy = fiscalyear.FiscalYear(f.fiscal_year)
  print('FY period:', fy.start.date(), '/', fy.end.date())

Output:

ISO: 2021-01-01  FY: 2022  FQ: 1  FM: 1
FY period: 2021-01-01 / 2021-12-31

Is this expected? if yes, how does one switch to standard year when following the calendar year?

Incorrect fiscal_day returned for last day of the year

The fiscal_day code incorrectly calculates the date delta. Examples:

>>> fiscalyear.FiscalDate(2016,9,30).fiscal_day
1
>>> fiscalyear.FiscalDate(2017,9,30).fiscal_day
365
>>> fiscalyear.FiscalDate(2018,9,30).fiscal_day
366

Fiscal Month Offset

Fiscal Month offset does not appear to match fiscal periods

>>>fiscalyear.setup_fiscal_calendar('previous', 12, 29)
>>>c=FiscalMonth(2021, 1)
>>>c.start
FiscalDateTime(2020, 12, 29, 0, 0)
>>>c.end
FiscalDateTime(2021, 1, 28, 23, 59, 59)
>>>a = FiscalDate(2021, 1, 28)
>>>b = FiscalDate(2021, 1, 29)
>>>a.fiscal_month
2
>>>b.fiscal_month
2
>>>c.fiscal_month
1
>>>a in c
True
>>>b in c
False

Support for week number of a date in a FiscalYear

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

[Question/Feature Request]: Convert from FY to CY

It would be convenient to be able to convert back to an ordinary datetime object. I could have missed this, but I didn't see it in the documentation. I imported the module and took a look around and didn't see explicit support for this.

Being in Canada, the conversion is straightforward using the FiscalYear data structure in my own code. But I figured this would be something nice to have in the fiscalyear package itself.

Support for a 4-4-5 calendar

A user is requesting support for a 4-4-5 calendar. This is quite a bit different than the original implementation I went with, but is inline with my original goals. This will likely require a major refactoring of the module, so it may take some time.

If you also would like to see support for 4-4-5, 4-5-4, or 5-4-4 calendars, give this post a ๐Ÿ‘. If you want to see support for a different calendar, open another issue. If you have any suggestions for how to implement a 4-4-5 calendar, including the UI for selecting which calendar to use, feel free to post a comment on this issue.

Syntactic sugar for getting the current Fiscal{Year,Quarter}

I think it would be nice if there was an easy way to get the current FiscalYear/FiscalQuarter.

This could easily be achieved by using a couple of classmethods. E.g.:

$ git diff
diff --git a/fiscalyear.py b/fiscalyear.py
index c6f8ddc..f7213d7 100644
--- a/fiscalyear.py
+++ b/fiscalyear.py
@@ -191,6 +191,11 @@ class FiscalYear(object):
         self._fiscal_year = fiscal_year
         return self
 
+    @classmethod
+    def current(cls):
+        today = datetime.date.today()
+        return cls(today.year)
+
     def __repr__(self):
         """Convert to formal string, for repr().
 
@@ -371,6 +376,11 @@ class FiscalQuarter(object):
         self._quarter = quarter
         return self
 
+    @classmethod
+    def current(cls):
+        today = datetime.date.today()
+        return cls(today.year, (today.month // 3) + 1)
+
     def __repr__(self):
         """Convert to formal string, for repr().

This way you could write:

In [3]: FiscalYear.current()
Out[3]: FiscalYear(2018)

In [4]: FiscalQuarter.current()
Out[4]: FiscalQuarter(2018, 1)

If you want, I can try to make a pull request.

Support February 29 month end date for leap year

Some companies use February for their end month for the fiscal year e.g. CarMax and their 10-K with last day as Feb 29, 2016 https://www.sec.gov/Archives/edgar/data/0001170010/000117001016000117/kmx0229201610-k.htm

Currently _check_day use 2001 a non-leap year to validate the day of the month:

def _check_day(month, day):
    """Check if day is a valid day of month.
    :param month: The month to test
    :param day: The day to test
    :return: The day
    :rtype: int
    :raises TypeError: If month or day is not an int or int-like string
    :raises ValueError: If month or day is out of range
    """
    month = _check_month(month)
    day = _check_int(day)

    # Find the last day of the month
    # Use a non-leap year
    max_day = calendar.monthrange(2001, month)[1]

Resolution would be to use year if provided e.g.

def _check_day(day, month, year=None):
    """Check if day is a valid day of month.
    :param day: The day to test
    :param month: The month to test
    :param day: Optional; the year to test; defaults to 2001 a non-leap year
    :return: The day
    :rtype: int
    :raises TypeError: If month or day is not an int or int-like string
    :raises ValueError: If month or day is out of range
    """
    year = year if year else 2001
    month = _check_month(month)
    day = _check_int(day)

    # Find the last day of the month
    max_day = calendar.monthrange(year, month)[1]

Note, in this example, changed order of args (for OCD purposes :) with year last as optional

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.