Skip to content

Instantly share code, notes, and snippets.

@mmynk
Last active March 17, 2025 07:16
Show Gist options
  • Save mmynk/493f74451596d78546bfa7d98a3bed03 to your computer and use it in GitHub Desktop.
Save mmynk/493f74451596d78546bfa7d98a3bed03 to your computer and use it in GitHub Desktop.
Substantial Presence Test Calculator
#!/usr/bin/env python3
# This script calculates the substantial presence test for US tax purposes.
# Example usage: ./residency_calc.py "2025-02-02,2025-03-03;2024-04-04,2024-05-05;2023-06-06,2023-07-07"
import argparse
from dataclasses import dataclass
from datetime import datetime
@dataclass
class TravelDetails:
entry: datetime
exit: datetime
def calculate_substantial_presence(travel_details: list[TravelDetails]) -> bool:
current_year = datetime.now().year
days_current_year = datetime.now().timetuple().tm_yday
days_last_year = 365
days_second_last_year = 365
for travel in travel_details:
if travel.exit.year == current_year:
exit_day = travel.exit if travel.exit < datetime.now() else datetime.now()
if travel.entry.year == current_year:
days_current_year_out = (exit_day - travel.entry).days
else:
days_current_year_out = (exit_day - datetime(current_year, 1, 1)).days
days_current_year -= (days_current_year_out - 1)
elif travel.exit.year == current_year - 1:
if travel.entry.year == current_year - 1:
days_last_year_out = (travel.exit - travel.entry).days
else:
days_last_year_out = (travel.exit - datetime(current_year - 1, 1
, 1)).days
days_last_year -= (days_last_year_out - 1)
elif travel.exit.year == current_year - 2:
if travel.entry.year == current_year - 2:
days_second_last_year_out = (travel.exit - travel.entry).days
else:
days_second_last_year_out = (travel.exit - datetime(current_year - 2, 1
, 1)).days
days_second_last_year -= (days_second_last_year_out - 1)
print(f'Days current year ({current_year}): {days_current_year}')
print(f'Days last year ({current_year - 1}): {days_last_year}')
print(f'Days year before last ({current_year - 2}): {days_second_last_year}')
return days_current_year >= 31 and days_current_year + (days_last_year // 3) + (days_second_last_year // 6) >= 183
def main():
parser = argparse.ArgumentParser(description='Calculate substantial presence test')
parser.add_argument('entries', type=str, help='List of entries and exits in the format "YYYY-MM-DD,YYYY-MM-DD;YYYY-MM-DD,YYYY-MM-DD"')
args = parser.parse_args()
travel_details = []
for entry_exit in args.entries.split(';'):
entry, exit = entry_exit.split(',')
travel_details.append(TravelDetails(datetime.strptime(entry, '%Y-%m-%d'), datetime.strptime(exit, '%Y-%m-%d')))
is_resident = calculate_substantial_presence(travel_details)
print('Resident' if is_resident else 'Non-resident')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment