Created
August 24, 2021 03:50
-
-
Save berglh/c44d71f1ea8983ed3e60ce5ef6667eb6 to your computer and use it in GitHub Desktop.
Work from Home Calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Discover all Working Days in Mon-Fri Pattern | |
Number of working days for set: 261, numpy: 261 should match | |
Set working days: ['2020-07-01', '2020-07-02', '2020-07-03', '2020-07-06', '2020-07-07', '2020-07-08', '2020-07-09', '2020-07-10', '2020-07-13', '2020-07-14', '2020-07-15', '2020-07-16', '2020-07-17', '2020-07-20', '2020-07-21', '2020-07-22', '2020-07-23', '2020-07-24', '2020-07-27', '2020-07-28', '2020-07-29', '2020-07-30', '2020-07-31', '2020-08-03', '2020-08-04', '2020-08-05', '2020-08-06', '2020-08-07', '2020-08-10', '2020-08-11', '2020-08-12', '2020-08-13', '2020-08-14', '2020-08-17', '2020-08-18', '2020-08-19', '2020-08-20', '2020-08-21', '2020-08-24', '2020-08-25', '2020-08-26', '2020-08-27', '2020-08-28', '2020-08-31', '2020-09-01', '2020-09-02', '2020-09-03', '2020-09-04', '2020-09-07', '2020-09-08', '2020-09-09', '2020-09-10', '2020-09-11', '2020-09-14', '2020-09-15', '2020-09-16', '2020-09-17', '2020-09-18', '2020-09-21', '2020-09-22', '2020-09-23', '2020-09-24', '2020-09-25', '2020-09-28', '2020-09-29', '2020-09-30', '2020-10-01', '2020-10-02', '2020-10-05', '2020-10-06', '2020-10-07', '2020-10-08', '2020-10-09', '2020-10-12', '2020-10-13', '2020-10-14', '2020-10-15', '2020-10-16', '2020-10-19', '2020-10-20', '2020-10-21', '2020-10-22', '2020-10-23', '2020-10-26', '2020-10-27', '2020-10-28', '2020-10-29', '2020-10-30', '2020-11-02', '2020-11-03', '2020-11-04', '2020-11-05', '2020-11-06', '2020-11-09', '2020-11-10', '2020-11-11', '2020-11-12', '2020-11-13', '2020-11-16', '2020-11-17', '2020-11-18', '2020-11-19', '2020-11-20', '2020-11-23', '2020-11-24', '2020-11-25', '2020-11-26', '2020-11-27', '2020-11-30', '2020-12-01', '2020-12-02', '2020-12-03', '2020-12-04', '2020-12-07', '2020-12-08', '2020-12-09', '2020-12-10', '2020-12-11', '2020-12-14', '2020-12-15', '2020-12-16', '2020-12-17', '2020-12-18', '2020-12-21', '2020-12-22', '2020-12-23', '2020-12-24', '2020-12-25', '2020-12-28', '2020-12-29', '2020-12-30', '2020-12-31', '2021-01-01', '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', '2021-01-11', '2021-01-12', '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-18', '2021-01-19', '2021-01-20', '2021-01-21', '2021-01-22', '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', '2021-01-29', '2021-02-01', '2021-02-02', '2021-02-03', '2021-02-04', '2021-02-05', '2021-02-08', '2021-02-09', '2021-02-10', '2021-02-11', '2021-02-12', '2021-02-15', '2021-02-16', '2021-02-17', '2021-02-18', '2021-02-19', '2021-02-22', '2021-02-23', '2021-02-24', '2021-02-25', '2021-02-26', '2021-03-01', '2021-03-02', '2021-03-03', '2021-03-04', '2021-03-05', '2021-03-08', '2021-03-09', '2021-03-10', '2021-03-11', '2021-03-12', '2021-03-15', '2021-03-16', '2021-03-17', '2021-03-18', '2021-03-19', '2021-03-22', '2021-03-23', '2021-03-24', '2021-03-25', '2021-03-26', '2021-03-29', '2021-03-30', '2021-03-31', '2021-04-01', '2021-04-02', '2021-04-05', '2021-04-06', '2021-04-07', '2021-04-08', '2021-04-09', '2021-04-12', '2021-04-13', '2021-04-14', '2021-04-15', '2021-04-16', '2021-04-19', '2021-04-20', '2021-04-21', '2021-04-22', '2021-04-23', '2021-04-26', '2021-04-27', '2021-04-28', '2021-04-29', '2021-04-30', '2021-05-03', '2021-05-04', '2021-05-05', '2021-05-06', '2021-05-07', '2021-05-10', '2021-05-11', '2021-05-12', '2021-05-13', '2021-05-14', '2021-05-17', '2021-05-18', '2021-05-19', '2021-05-20', '2021-05-21', '2021-05-24', '2021-05-25', '2021-05-26', '2021-05-27', '2021-05-28', '2021-05-31', '2021-06-01', '2021-06-02', '2021-06-03', '2021-06-04', '2021-06-07', '2021-06-08', '2021-06-09', '2021-06-10', '2021-06-11', '2021-06-14', '2021-06-15', '2021-06-16', '2021-06-17', '2021-06-18', '2021-06-21', '2021-06-22', '2021-06-23', '2021-06-24', '2021-06-25', '2021-06-28', '2021-06-29', '2021-06-30'] | |
Eliminate Queensland Holidays from Working Dates | |
Excluding The Royal Queensland Show [2020-08-14] Queensland holiday | |
Excluding Anzac Day (Observed) [2021-04-26] Queensland holiday | |
Excluding Labour Day [2021-05-03] Queensland holiday | |
Excluding Good Friday [2021-04-02] Queensland holiday | |
Excluding Boxing Day (Observed) [2020-12-28] Queensland holiday | |
Excluding Christmas Day [2020-12-25] Queensland holiday | |
Excluding Queen's Birthday [2020-10-05] Queensland holiday | |
Excluding Australia Day [2021-01-26] Queensland holiday | |
Excluding Easter Monday [2021-04-05] Queensland holiday | |
Excluding New Year's Day [2021-01-01] Queensland holiday | |
251 working days remaining | |
Eliminate Dates of Leave from Working Dates | |
Removing leave from working days: ['2020-12-24', '2020-12-29', '2020-12-30', '2020-12-31', '2021-04-06', '2021-04-07', '2021-04-28', '2021-04-29', '2021-05-24'] | |
242 working days remaining | |
Discover working days during lockdowns | |
The 2020 First Lockdown (98 Days) dates ['2020-07-01', '2020-07-02', '2020-07-03', '2020-07-06', '2020-07-07', '2020-07-08', '2020-07-09', '2020-07-10', '2020-07-13'] were worked from home | |
The 2021-W01 Lockdown (January) dates ['2021-01-08', '2021-01-11', '2021-01-12'] were worked from home | |
The 2021-W13 Lockdown (Easter Lead-up) dates ['2021-03-29', '2021-03-30', '2021-03-31', '2021-04-01'] were worked from home | |
The 2021-W26 Lockdown (June) dates ['2021-06-29', '2021-06-30'] were worked from home | |
Discover working days during work partial work from home period | |
Work from home period dates: ['2020-07-14', '2020-07-17', '2020-07-21', '2020-07-24', '2020-07-28', '2020-07-31', '2020-08-04', '2020-08-07', '2020-08-11', '2020-08-18', '2020-08-21', '2020-08-25', '2020-08-28', '2020-09-01', '2020-09-04', '2020-09-08', '2020-09-11', '2020-09-15', '2020-09-18', '2020-09-22', '2020-09-25', '2020-09-29', '2020-10-02', '2020-10-06', '2020-10-09', '2020-10-13', '2020-10-16', '2020-10-20', '2020-10-23', '2020-10-27', '2020-10-30', '2020-11-03', '2020-11-06', '2020-11-10', '2020-11-13', '2020-11-17', '2020-11-20', '2020-11-24', '2020-11-27', '2020-12-01', '2020-12-04', '2020-12-08', '2020-12-11', '2020-12-15', '2020-12-18', '2020-12-22', '2021-01-05', '2021-01-08', '2021-01-12', '2021-01-15', '2021-01-19', '2021-01-22', '2021-01-29', '2021-02-02', '2021-02-05', '2021-02-09', '2021-02-12', '2021-02-16', '2021-02-19', '2021-02-23', '2021-02-26', '2021-03-02', '2021-03-05', '2021-03-09', '2021-03-12', '2021-03-16', '2021-03-19', '2021-03-23', '2021-03-26', '2021-04-09', '2021-04-13', '2021-04-16', '2021-04-20', '2021-04-23', '2021-04-27', '2021-04-30', '2021-05-04', '2021-05-07', '2021-05-11', '2021-05-14', '2021-05-18', '2021-05-21', '2021-05-25', '2021-05-28', '2021-06-01', '2021-06-04', '2021-06-08', '2021-06-11', '2021-06-15', '2021-06-18', '2021-06-22', '2021-06-25', '2021-06-29'] | |
Total Work From Home Days: 108 | |
List of Work From Home Days: ['2020-07-01', '2020-07-02', '2020-07-03', '2020-07-06', '2020-07-07', '2020-07-08', '2020-07-09', '2020-07-10', '2020-07-13', '2020-07-14', '2020-07-17', '2020-07-21', '2020-07-24', '2020-07-28', '2020-07-31', '2020-08-04', '2020-08-07', '2020-08-11', '2020-08-18', '2020-08-21', '2020-08-25', '2020-08-28', '2020-09-01', '2020-09-04', '2020-09-08', '2020-09-11', '2020-09-15', '2020-09-18', '2020-09-22', '2020-09-25', '2020-09-29', '2020-10-02', '2020-10-06', '2020-10-09', '2020-10-13', '2020-10-16', '2020-10-20', '2020-10-23', '2020-10-27', '2020-10-30', '2020-11-03', '2020-11-06', '2020-11-10', '2020-11-13', '2020-11-17', '2020-11-20', '2020-11-24', '2020-11-27', '2020-12-01', '2020-12-04', '2020-12-08', '2020-12-11', '2020-12-15', '2020-12-18', '2020-12-22', '2021-01-05', '2021-01-08', '2021-01-11', '2021-01-12', '2021-01-15', '2021-01-19', '2021-01-22', '2021-01-29', '2021-02-02', '2021-02-05', '2021-02-09', '2021-02-12', '2021-02-16', '2021-02-19', '2021-02-23', '2021-02-26', '2021-03-02', '2021-03-05', '2021-03-09', '2021-03-12', '2021-03-16', '2021-03-19', '2021-03-23', '2021-03-26', '2021-03-29', '2021-03-30', '2021-03-31', '2021-04-01', '2021-04-09', '2021-04-13', '2021-04-16', '2021-04-20', '2021-04-23', '2021-04-27', '2021-04-30', '2021-05-04', '2021-05-07', '2021-05-11', '2021-05-14', '2021-05-18', '2021-05-21', '2021-05-25', '2021-05-28', '2021-06-01', '2021-06-04', '2021-06-08', '2021-06-11', '2021-06-15', '2021-06-18', '2021-06-22', '2021-06-25', '2021-06-29', '2021-06-30'] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from datetime import date | |
import numpy as np | |
import pandas as pd | |
import holidays | |
""" | |
work_from_home is a script to calculate the days worked from home for tax purposes | |
variables define days of leave, lockdown periods and partial work from home periods | |
""" | |
tax_year_start = date.fromisoformat('2020-07-01') | |
tax_year_end = date.fromisoformat('2021-06-30') | |
""" | |
weekmaskstr or array_like of bool, optional | |
A seven-element array indicating which of Monday through Sunday are valid days. May be specified as a length-seven list or array, like [1,1,1,1,1,0,0]; | |
a length-seven string, like ‘1111100’; or a string like “Mon Tue Wed Thu Fri”, made up of 3-character abbreviations for weekdays, optionally separated by white space. | |
Valid abbreviations are: Mon Tue Wed Thu Fri Sat Sun | |
""" | |
# worked tuesday and friday from home during partial wfh | |
wfh_weekmask = '0100100' | |
# range of dates I worked from home not in lockdown | |
wfh_periods = [ | |
(date.fromisoformat('2020-07-13'), date.fromisoformat('2021-01-08')), | |
(date.fromisoformat('2021-01-12'), date.fromisoformat('2021-03-29')), | |
(date.fromisoformat('2021-04-02'), date.fromisoformat('2021-06-29')), | |
] | |
leave = [ | |
(date.fromisoformat('2020-12-24'), date.fromisoformat('2020-12-24')), | |
(date.fromisoformat('2020-12-29'), date.fromisoformat('2020-12-31')), | |
(date.fromisoformat('2021-04-06'), date.fromisoformat('2021-04-07')), | |
(date.fromisoformat('2021-04-28'), date.fromisoformat('2021-04-29')), | |
(date.fromisoformat('2021-05-24'), date.fromisoformat('2021-05-24')) | |
] | |
lockdowns = { | |
'2020 First Lockdown (98 Days)': (date.fromisoformat('2020-07-01'), date.fromisoformat('2020-07-13')), | |
'2021-W01 Lockdown (January)': (date.fromisoformat('2021-01-08'), date.fromisoformat('2021-01-12')), | |
'2021-W13 Lockdown (Easter Lead-up)': (date.fromisoformat('2021-03-29'), date.fromisoformat('2021-04-02')), | |
'2021-W26 Lockdown (June)': (date.fromisoformat('2021-06-29'), date.fromisoformat('2021-07-04')) | |
} | |
# collect all the work from home into this final set | |
wfh_dates = set() | |
if __name__ == "__main__": | |
""" | |
Calculates the number of working days each year worked from home during lockdowns & partial WFH periods | |
""" | |
print(f"\nDiscover all Working Days in Mon-Fri Pattern\n") | |
# busday_count is exclusive of end date | |
working_day_count = np.busday_count(tax_year_start.isoformat(), tax_year_end.isoformat())+1 | |
# first discover all the working days | |
working_days = set() | |
for d in pd.date_range(tax_year_start,tax_year_end,freq='d'): | |
#print(d.strftime("%Y-%m-%d")) | |
if np.is_busday(d.strftime("%Y-%m-%d")): | |
working_days.add(d) | |
print(f"Number of working days for set: {len(working_days)}, numpy: {working_day_count} should match") | |
print(f"Set working days: {[d.strftime('%Y-%m-%d') for d in sorted(working_days)]}") | |
# if date is public holidays, remove from the set | |
print(f"\nEliminate Queensland Holidays from Working Dates\n") | |
# import queensland public holidays | |
qld_holidays = holidays.Australia(prov='QLD') | |
remove_dates = [] | |
for d in working_days: | |
if d.strftime('%Y-%m-%d') in qld_holidays: | |
print(f"Excluding {qld_holidays.get(d.strftime('%Y-%m-%d'))} [{d.strftime('%Y-%m-%d')}] Queensland holiday") | |
remove_dates.append(d) | |
for d in remove_dates: | |
working_days.remove(d) | |
print(f"{len(working_days)} working days remaining") | |
# generate set of leave dates, and remove from working day set | |
print(f"\nEliminate Dates of Leave from Working Dates\n") | |
remove_dates = [] | |
for l in leave: | |
for d in pd.date_range(l[0],l[1],freq='d'): | |
if d in working_days: | |
remove_dates.append(d) | |
print(f"Removing leave from working days: {[d.strftime('%Y-%m-%d') for d in sorted(remove_dates)]}") | |
for d in remove_dates: | |
working_days.remove(d) | |
print(f"{len(working_days)} working days remaining") | |
# find all working days during the lockdown periods | |
print(f"\nDiscover working days during lockdowns\n") | |
for k in lockdowns: | |
worked_dates = [] | |
for d in pd.date_range(lockdowns[k][0],lockdowns[k][1],freq='d'): | |
if d in working_days: | |
worked_dates.append(d) | |
wfh_dates.add(d) | |
print(f"The {k} dates {[d.strftime('%Y-%m-%d') for d in sorted(worked_dates)]} were worked from home") | |
# find all working days during the partial WFH periods using the wfh_weekmask | |
print(f"\nDiscover working days during work partial work from home period\n") | |
worked_dates = [] | |
for t in wfh_periods: | |
for d in pd.date_range(t[0],t[1],freq='d'): | |
if d in working_days and np.is_busday(d.strftime("%Y-%m-%d"), weekmask=wfh_weekmask): | |
worked_dates.append(d) | |
wfh_dates.add(d) | |
print(f"Work from home period dates: {[d.strftime('%Y-%m-%d') for d in sorted(worked_dates)]}") | |
# returning results | |
print(f"\nTotal Work From Home Days: {len(wfh_dates)}") | |
print(f"\nList of Work From Home Days: {[d.strftime('%Y-%m-%d') for d in sorted(wfh_dates)]}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment