fiscalyear¶
fiscalyear is a small, lightweight Python module providing helpful utilities for managing the fiscal calendar. It is designed as an extension of the built-in datetime and calendar modules, adding the ability to query the fiscal year, fiscal quarter, fiscal month, and fiscal day of a date or datetime object.
Basic Usage¶
fiscalyear
provides several useful classes.
FiscalYear¶
The FiscalYear
class provides an object for storing information about the start and end of a particular fiscal year.
>>> from fiscalyear import *
>>> a = FiscalYear(2017)
>>> a.start
FiscalDateTime(2016, 10, 1, 0, 0)
>>> a.end
FiscalDateTime(2017, 9, 30, 23, 59, 59)
>>> a.isleap
False
You can also get the current FiscalYear
with:
>>> FiscalYear.current()
FiscalYear(2018)
FiscalQuarter¶
The FiscalYear
class also allows you to query information about a specific fiscal quarter.
>>> a.q3.start
FiscalDateTime(2017, 4, 1, 0, 0)
>>> a.q3.end
FiscalDateTime(2017, 6, 30, 23, 59, 59)
These objects represent the standalone FiscalQuarter
class.
>>> b = FiscalQuarter(2017, 3)
>>> b.start
FiscalDateTime(2017, 4, 1, 0, 0)
>>> b.end
FiscalDateTime(2017, 6, 30, 23, 59, 59)
>>> a.q3 == b
True
>>> b in a
True
>>> b.next_fiscal_quarter
FiscalQuarter(2017, 4)
You can also get the current FiscalQuarter
with:
>>> FiscalQuarter.current()
FiscalQuarter(2018, 2)
FiscalMonth¶
The FiscalMonth
class allows you to keep track of the fiscal month.
>>> c = FiscalMonth(2017, 9)
>>> c.start
FiscalDateTime(2017, 6, 1, 0, 0)
>>> c.end
FiscalDateTime(2017, 6, 30, 23, 59, 59)
>>> c in a
True
>>> c in b
True
>>> c.next_fiscal_month
FiscalMonth(2017, 10)
You can also get the current FiscalMonth
with:
>>> FiscalMonth.current()
FiscalMonth(2018, 4)
FiscalDay¶
To keep track of the fiscal day, use the FiscalDay
class.
>>> d = FiscalDay(2017, 250)
>>> d.start
FiscalDateTime(2017, 6, 6, 0, 0)
>>> d.end
FiscalDateTime(2017, 6, 6, 23, 59, 59)
>>> d in a
True
>>> d in b
True
>>> d in c
True
>>> d.next_fiscal_day
FiscalDay(2017, 251)
You can also get the current FiscalDay
with:
>>> FiscalDay.current()
FiscalDay(2018, 94)
FiscalDateTime¶
The start and end of each of the above objects are stored as instances of the FiscalDateTime
class. This class provides all of the same features as the datetime
class, with the addition of the ability to query the fiscal year, fiscal quarter, fiscal month, and fiscal day.
>>> e = FiscalDateTime.now()
>>> e
FiscalDateTime(2017, 4, 8, 20, 30, 31, 105323)
>>> e.fiscal_year
2017
>>> e.fiscal_quarter
3
>>> e.next_fiscal_quarter
FiscalQuarter(2017, 4)
>>> e.fiscal_month
7
>>> e.fiscal_day
190
FiscalDate¶
If you don’t care about the time component of the FiscalDateTime
class, the FiscalDate
class is right for you.
>>> f = FiscalDate.today()
>>> f
FiscalDate(2017, 4, 8)
>>> f.fiscal_year
2017
>>> f.prev_fiscal_year
FiscalYear(2016)
Advanced Usage¶
Not every government, business, and institution uses the same fiscal calendar. By default, the fiscalyear
module uses the fiscal calendar of the U.S. federal government. For example, the 2017 fiscal year starts on October 1st, 2016 and ends on September 30th, 2017. In contrast, the United Kingdom fiscal year is completely different. For personal tax purposes, the 2017 fiscal year in the U.K. starts on April 6th, 2017 and ends on April 5th, 2018. The fiscalyear
module allows you to change the start date of the fiscal year to suit your needs.
Changing the fiscal calendar¶
In order to explain how to change the fiscal calendar, let’s use the U.K. personal tax financial year as an example.
>>> import fiscalyear
>>> a = fiscalyear.FiscalYear(2017)
Start year¶
The first difference you’ll notice between the U.S. and the U.K. fiscal calendars is that in the U.S., the 2017 fiscal year actually starts in 2016, while in the U.K. it starts in 2017. To control this, change the start year from 'previous'
to 'same'
.
>>> a.start.year
2016
>>> fiscalyear.setup_fiscal_calendar(start_year='same')
>>> a.start.year
2017
Now that the start year is right, let’s change the start month.
Start month¶
The start month can be any valid month.
>>> a.start.month
10
>>> fiscalyear.setup_fiscal_calendar(start_month=4)
>>> a.start.month
4
Finally, let’s change the start day.
Start day¶
The start day can be any valid day in the chosen month.
>>> a.start.day
1
>>> fiscalyear.setup_fiscal_calendar(start_day=6)
>>> a.start.day
6
Putting everything together, we can see that the definition of the start and end of the fiscal calendar has been globally changed for all objects.
>>> a.start
FiscalDateTime(2017, 4, 6, 0, 0)
>>> a.end
FiscalDateTime(2018, 4, 5, 23, 59, 59)
Of course, we can change all of these variables at the same time like so:
>>> fiscalyear.setup_fiscal_calendar('same', 4, 6)
Temporarily changing the fiscal calendar¶
If you need to work with multiple fiscal calendars in the same program, it may be beneficial to be able to temporarily change the fiscal calendar. The fiscalyear
module provides a fiscal_calendar
context manager to handle this.
>>> from fiscalyear import *
>>> a = FiscalYear(2017)
>>> a.start
FiscalDateTime(2016, 10, 1, 0, 0)
>>> with fiscal_calendar(start_month=6):
... a.start
...
FiscalDateTime(2016, 6, 1, 0, 0)
>>> a.start
FiscalDateTime(2016, 10, 1, 0, 0)
To recreate our previous example, this would look like:
>>> with fiscal_calendar('same', 4, 6):
... a.start
...
FiscalDateTime(2017, 4, 6, 0, 0)
Or in a for-loop:
calendars = [
('previous', 10, 1),
('same', 4, 6),
...
]
for calendar in calendars:
with fiscal_calendar(*calendar):
# do stuff
Installation¶
fiscalyear
has no dependencies, making it simple and easy to install. There are multiple ways to install the fiscalyear
module.
pip¶
The recommended way to install fiscalyear
is with pip
.
$ pip install fiscalyear
The fiscalyear module will now appear with your base Python installation.
Anaconda¶
You can also install fiscalyear
with the conda
package manager.
$ conda install -c conda-forge fiscalyear
Spack¶
If you work in an HPC environment, the Spack package manager can be used to install fiscalyear
as well.
$ spack install py-fiscalyear
$ spack load py-fiscalyear
See the Spack Documentation to get started.
Source¶
If you’re up for it, you can also install fiscalyear
from source. Simply clone the repository.
$ git clone https://github.com/adamjstewart/fiscalyear.git
Now build the module.
$ python setup.py build
Finally, install the package to somewhere in your PYTHONPATH
.
$ python setup.py install --prefix=/path/to/installation/prefix
Drag-n-Drop¶
If you want to vendor fiscalyear
with your Python package, you can always download the source code. fiscalyear
is composed of a single file, making it easy to drag-n-drop to your current directory and import.
Testing¶
fiscalyear
comes with a full test-suite called test_fiscalyear
. To run the test-suite, you
will need to install the following packages:
Running tests¶
Once pytest
is installed, simply cd
to the root directory of fiscalyear
and run the pytest
command.
$ git clone https://github.com/adamjstewart/fiscalyear.git
$ cd fiscalyear
$ pytest
============================ test session starts =============================
platform darwin -- Python 2.7.13, pytest-3.0.5, py-1.4.32, pluggy-0.4.0
rootdir: /Users/Adam/fiscalyear, inifile:
plugins: cov-2.3.1
collected 66 items
test_fiscalyear.py ..................................................................
========================= 66 passed in 0.21 seconds ==========================
pytest
provides automatic test detection that locates the test_fiscalyear.py
file and runs tests that begin with test_*
.
Continuous Integration (CI)¶
In order to prevent bugs from being introduced into the code, fiscalyear
uses GitHub Actions for continuous integration. After every commit or pull request, GitHub Actions automatically runs the test-suite across all supported versions of Python 2 and 3. This has the added benefit of preventing incompatibilities between different Python versions.
Coverage¶
fiscalyear
uses pytest-cov
to determine the percentage of the code base that is covered by unit tests. You will need to install the following packages to run the coverage tests yourself.
Running coverage tests¶
Once you have the dependencies installed, you can run the coverage tests locally.
$ pytest --cov=fiscalyear
============================ test session starts =============================
platform darwin -- Python 2.7.13, pytest-3.0.5, py-1.4.32, pluggy-0.4.0
rootdir: /Users/Adam/fiscalyear, inifile:
plugins: cov-2.3.1
collected 66 items
test_fiscalyear.py ..................................................................
---------- coverage: platform darwin, python 2.7.13-final-0 ----------
Name Stmts Miss Cover
-----------------------------------
fiscalyear.py 233 0 100%
========================= 66 passed in 0.21 seconds ==========================
fiscalyear
always strives for 100% coverage, and won’t accept pull requests that aren’t covered by unit tests.
Documentation¶
fiscalyear
uses Sphinx and the Read the Docs Theme to generate its documentation. The documentation is proudly hosted on Read the Docs.
Building the documentation¶
To build the documentation, you’ll need to have sphinx
and sphinx_rtd_theme
installed. Then, cd
to the docs
directory and use the Makefile
to build everything.
$ cd docs
$ make html
Building the documentation with setuptools¶
Alternatively, the documentation can be built with the following command:
$ python setup.py build_sphinx
Continuous Integration (CI)¶
Every time a change is made to the documentation and pushed to GitHub, Read the Docs automatically rebuilds the documentation, keeping everything in sync and up-to-date.
API Docs¶
Utilities for managing the fiscal calendar.
-
class
fiscalyear.
FiscalDate
¶ A wrapper around the builtin datetime.date class that provides the following attributes.
-
ctime
()¶ Return ctime() style string.
-
day
¶
-
fiscal_day
¶ Returns: The fiscal day Return type: int
-
fiscal_month
¶ Returns: The fiscal month Return type: int
-
fiscal_quarter
¶ Returns: The fiscal quarter Return type: int
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
fromisoformat
()¶ str -> Construct a date from the output of date.isoformat()
-
fromordinal
()¶ int -> date corresponding to a proleptic Gregorian ordinal.
-
fromtimestamp
()¶ timestamp -> local date from a POSIX timestamp (like time.time()).
-
isocalendar
()¶ Return a 3-tuple containing ISO year, week number, and weekday.
-
isoformat
()¶ Return string in ISO 8601 format, YYYY-MM-DD.
-
isoweekday
()¶ Return the day of the week represented by the date. Monday == 1 … Sunday == 7
-
max
= datetime.date(9999, 12, 31)¶
-
min
= datetime.date(1, 1, 1)¶
-
month
¶
-
next_fiscal_month
¶ Returns: The next fiscal month Return type: FiscalMonth
-
next_fiscal_quarter
¶ Returns: The next fiscal quarter Return type: FiscalQuarter
-
next_fiscal_year
¶ Returns: The next fiscal year Return type: FiscalYear
-
prev_fiscal_month
¶ Returns: The previous fiscal month Return type: FiscalMonth
-
prev_fiscal_quarter
¶ Returns: The previous fiscal quarter Return type: FiscalQuarter
-
prev_fiscal_year
¶ Returns: The previous fiscal year Return type: FiscalYear
-
replace
()¶ Return date with new specified fields.
-
resolution
= datetime.timedelta(days=1)¶
-
strftime
()¶ format -> strftime() style string.
-
timetuple
()¶ Return time tuple, compatible with time.localtime().
-
today
()¶ Current date or datetime: same as self.__class__.fromtimestamp(time.time()).
-
toordinal
()¶ Return proleptic Gregorian ordinal. January 1 of year 1 is day 1.
-
weekday
()¶ Return the day of the week represented by the date. Monday == 0 … Sunday == 6
-
year
¶
-
-
class
fiscalyear.
FiscalDateTime
¶ A wrapper around the builtin datetime.datetime class that provides the following attributes.
-
astimezone
()¶ tz -> convert to local time in new timezone tz
-
combine
()¶ date, time -> datetime with same date and time fields
-
ctime
()¶ Return ctime() style string.
-
date
()¶ Return date object with same year, month and day.
-
day
¶
-
dst
()¶ Return self.tzinfo.dst(self).
-
fiscal_day
¶ Returns: The fiscal day Return type: int
-
fiscal_month
¶ Returns: The fiscal month Return type: int
-
fiscal_quarter
¶ Returns: The fiscal quarter Return type: int
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
fold
¶
-
fromisoformat
()¶ string -> datetime from datetime.isoformat() output
-
fromordinal
()¶ int -> date corresponding to a proleptic Gregorian ordinal.
-
fromtimestamp
()¶ timestamp[, tz] -> tz’s local time from POSIX timestamp.
-
hour
¶
-
isocalendar
()¶ Return a 3-tuple containing ISO year, week number, and weekday.
-
isoformat
()¶ [sep] -> string in ISO 8601 format, YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM]. sep is used to separate the year from the time, and defaults to ‘T’. timespec specifies what components of the time to include (allowed values are ‘auto’, ‘hours’, ‘minutes’, ‘seconds’, ‘milliseconds’, and ‘microseconds’).
-
isoweekday
()¶ Return the day of the week represented by the date. Monday == 1 … Sunday == 7
-
max
= datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)¶
-
microsecond
¶
-
min
= datetime.datetime(1, 1, 1, 0, 0)¶
-
minute
¶
-
month
¶
-
next_fiscal_month
¶ Returns: The next fiscal month Return type: FiscalMonth
-
next_fiscal_quarter
¶ Returns: The next fiscal quarter Return type: FiscalQuarter
-
next_fiscal_year
¶ Returns: The next fiscal year Return type: FiscalYear
-
now
()¶ Returns new datetime object representing current time local to tz.
- tz
- Timezone object.
If no tz is specified, uses local timezone.
-
prev_fiscal_month
¶ Returns: The previous fiscal month Return type: FiscalMonth
-
prev_fiscal_quarter
¶ Returns: The previous fiscal quarter Return type: FiscalQuarter
-
prev_fiscal_year
¶ Returns: The previous fiscal year Return type: FiscalYear
-
replace
()¶ Return datetime with new specified fields.
-
resolution
= datetime.timedelta(microseconds=1)¶
-
second
¶
-
strftime
()¶ format -> strftime() style string.
-
strptime
()¶ string, format -> new datetime parsed from a string (like time.strptime()).
-
time
()¶ Return time object with same time but with tzinfo=None.
-
timestamp
()¶ Return POSIX timestamp as float.
-
timetuple
()¶ Return time tuple, compatible with time.localtime().
-
timetz
()¶ Return time object with same time and tzinfo.
-
today
()¶ Current date or datetime: same as self.__class__.fromtimestamp(time.time()).
-
toordinal
()¶ Return proleptic Gregorian ordinal. January 1 of year 1 is day 1.
-
tzinfo
¶
-
tzname
()¶ Return self.tzinfo.tzname(self).
-
utcfromtimestamp
()¶ Construct a naive UTC datetime from a POSIX timestamp.
-
utcnow
()¶ Return a new datetime representing UTC day and time.
-
utcoffset
()¶ Return self.tzinfo.utcoffset(self).
-
utctimetuple
()¶ Return UTC time tuple, compatible with time.localtime().
-
weekday
()¶ Return the day of the week represented by the date. Monday == 0 … Sunday == 6
-
year
¶
-
-
class
fiscalyear.
FiscalDay
¶ A class representing a single fiscal day.
Constructor.
Parameters: - fiscal_year (int or str) – The fiscal year
- fiscal_day (int or str) – The fiscal day
Returns: A newly constructed FiscalDay object
Return type: Raises: - TypeError – If fiscal_year or fiscal_day is not an int or int-like string
- ValueError – If fiscal_year or fiscal_day is out of range
-
classmethod
current
()¶ Alternative constructor. Returns the current FiscalDay.
Returns: A newly constructed FiscalDay object Return type: FiscalDay
-
end
¶ Returns: End of the fiscal day Return type: FiscalDateTime
-
fiscal_day
¶ Returns: The fiscal day Return type: int
-
fiscal_month
¶ Returns: The fiscal month Return type: int
-
fiscal_quarter
¶ Returns: The fiscal quarter Return type: int
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
start
¶ Returns: Start of the fiscal day Return type: FiscalDateTime
-
class
fiscalyear.
FiscalMonth
¶ A class representing a single fiscal month.
Constructor.
Parameters: - fiscal_year (int or str) – The fiscal year
- fiscal_month (int or str) – The fiscal month
Returns: A newly constructed FiscalMonth object
Return type: Raises: - TypeError – If fiscal_year or fiscal_month is not an int or int-like string
- ValueError – If fiscal_year or fiscal_month is out of range
-
classmethod
current
()¶ Alternative constructor. Returns the current FiscalMonth.
Returns: A newly constructed FiscalMonth object Return type: FiscalMonth
-
end
¶ Returns: End of the fiscal month Return type: FiscalDateTime
-
fiscal_month
¶ Returns: The fiscal month Return type: int
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
next_fiscal_month
¶ Returns: The next fiscal month Return type: FiscalMonth
-
prev_fiscal_month
¶ Returns: The previous fiscal month Return type: FiscalMonth
-
start
¶ Returns: Start of the fiscal month Return type: FiscalDateTime
-
class
fiscalyear.
FiscalQuarter
¶ A class representing a single fiscal quarter.
Constructor.
Parameters: - fiscal_year (int or str) – The fiscal year
- fiscal_quarter (int or str) – The fiscal quarter
Returns: A newly constructed FiscalQuarter object
Return type: Raises: - TypeError – If fiscal_year or fiscal_quarter is not an int or int-like string
- ValueError – If fiscal_year or fiscal_quarter is out of range
-
classmethod
current
()¶ Alternative constructor. Returns the current FiscalQuarter.
Returns: A newly constructed FiscalQuarter object Return type: FiscalQuarter
-
end
¶ Returns: The end of the fiscal quarter Return type: FiscalDateTime
-
fiscal_quarter
¶ Returns: The fiscal quarter Return type: int
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
next_fiscal_quarter
¶ Returns: The next fiscal quarter Return type: FiscalQuarter
-
prev_fiscal_quarter
¶ Returns: The previous fiscal quarter Return type: FiscalQuarter
-
start
¶ Returns: The start of the fiscal quarter Return type: FiscalDateTime
-
class
fiscalyear.
FiscalYear
¶ A class representing a single fiscal year.
Constructor.
Parameters: fiscal_year (int or str) – The fiscal year
Returns: A newly constructed FiscalYear object
Return type: Raises: - TypeError – If fiscal_year is not an int or int-like string
- ValueError – If fiscal_year is out of range
-
classmethod
current
()¶ Alternative constructor. Returns the current FiscalYear.
Returns: A newly constructed FiscalYear object Return type: FiscalYear
-
end
¶ Returns: End of the fiscal year Return type: FiscalDateTime
-
fiscal_year
¶ Returns: The fiscal year Return type: int
-
isleap
¶ returns: True if the fiscal year contains a leap day, else False :rtype: bool
-
next_fiscal_year
¶ Returns: The next fiscal year Return type: FiscalYear
-
prev_fiscal_year
¶ Returns: The previous fiscal year Return type: FiscalYear
-
q1
¶ Returns: The first quarter of the fiscal year Return type: FiscalQuarter
-
q2
¶ Returns: The second quarter of the fiscal year Return type: FiscalQuarter
-
q3
¶ Returns: The third quarter of the fiscal year Return type: FiscalQuarter
-
q4
¶ Returns: The fourth quarter of the fiscal year Return type: FiscalQuarter
-
start
¶ Returns: Start of the fiscal year Return type: FiscalDateTime
-
fiscalyear.
fiscal_calendar
(start_year=None, start_month=None, start_day=None)¶ A context manager that lets you modify the start of the fiscal calendar inside the scope of a with-statement.
Parameters: - start_year (str) – Relationship between the start of the fiscal year and
the calendar year. Possible values:
'previous'
or'same'
. - start_month (int or str) – The first month of the fiscal year
- start_day (int or str) – The first day of the first month of the fiscal year
Raises: - ValueError – If
start_year
is not'previous'
or'same'
- TypeError – If
start_month
orstart_day
is not an int or int-like string - ValueError – If
start_month
orstart_day
is out of range
- start_year (str) – Relationship between the start of the fiscal year and
the calendar year. Possible values:
-
fiscalyear.
setup_fiscal_calendar
(start_year=None, start_month=None, start_day=None)¶ Modify the start of the fiscal calendar.
Parameters: - start_year (str) – Relationship between the start of the fiscal year and
the calendar year. Possible values:
'previous'
or'same'
. - start_month (int or str) – The first month of the fiscal year
- start_day (int or str) – The first day of the first month of the fiscal year
Raises: - ValueError – If
start_year
is not'previous'
or'same'
- TypeError – If
start_month
orstart_day
is not an int or int-like string - ValueError – If
start_month
orstart_day
is out of range
- start_year (str) – Relationship between the start of the fiscal year and
the calendar year. Possible values: