Physical presence requirements for Canadian Citizenship

To be eligible for Canadian citizenship, you must have been physically present in Canada for at least 1,095 days in the five years immediately before the date of your application. We encourage applicants to apply with more than the minimum requirement of 1,095 days of physical presence, to account for any miscalculations of absences, or any other aspect that could lower the physical presence total below 1,095 days. Please note that you cannot meet the physical presence requirement without a minimum of two (2) years as a permanent resident.

When calculating your time in Canada:

  • only the five (5) years immediately before the date of your application are taken into account;
  • each day you were physically present in Canada as an authorized temporary resident or protected person before you became a permanent resident counts as half a day (up to a maximum of 365 days);
  • each day you were physically present in Canada after you became a permanent resident counts as one day;
  • time spent serving a sentence for an offence in Canada (e.g. serving a term of imprisonment, probation and/or parole) cannot be counted towards your physical presence - there are some exceptions.

In order to help you decide when to apply, the physical presence calculator calculates if and when you will meet the 1,095 day requirement.

Source: https://eservices.cic.gc.ca/rescalc/resCalcStartNew.do?lang=en

In [1]:
from datetime import datetime, timezone, timedelta
from dateutil.parser import parse
from dateutil import tz
from memair import Memair
import time

# Memair Access Token
access_token = 'foo'
# Date of permanent residency
pr_date = datetime(2016,2,14).date()
In [2]:
canadian_timezones = ['America/Atikokan', 'America/Blanc-Sablon', 'America/Cambridge_Bay',
                      'America/Creston', 'America/Dawson', 'America/Dawson_Creek',
                      'America/Edmonton', 'America/Fort_Nelson', 'America/Glace_Bay',
                      'America/Goose_Bay', 'America/Halifax', 'America/Inuvik',
                      'America/Iqaluit', 'America/Moncton', 'America/Montreal',
                      'America/Nipigon', 'America/Pangnirtung', 'America/Rainy_River',
                      'America/Rankin_Inlet', 'America/Regina', 'America/Resolute',
                      'America/St_Johns', 'America/Swift_Current', 'America/Thunder_Bay',
                      'America/Toronto', 'America/Vancouver', 'America/Whitehorse',
                      'America/Winnipeg', 'America/Yellowknife']
user = Memair(access_token)
after = -1
dates_in_canada_post_pr = set()
dates_in_canada_pre_pr = set()
earliest_eligible_date = datetime.now().date() - timedelta(days=365*5)

print('Collecting & processing locations')

while True:
    query = f'''
      query {{
        Locations(
          first: 10000
          after: {after}
          from_timestamp: "{earliest_eligible_date}"
          order: desc
          order_by: timestamp
        )
        {{
          id
          timestamp
          timezone
        }}
      }}

    '''
    response = user.query(query)

    if len(response['data']['Locations']) == 0:
        break
        
    for location in response['data']['Locations']:
        if location['timezone'] in canadian_timezones:
            timezone = tz.gettz(location['timezone'])
            date = parse(location['timestamp']).astimezone(tz=timezone).date()
            if date >= pr_date:
                dates_in_canada_post_pr.add(date)
            else:
                dates_in_canada_pre_pr.add(date)

    after = response['data']['Locations'][-1]['id']
    time.sleep(5)
    print('. ', end='')

print(f'\nFinished processing!')
Collecting & processing locations
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
Finished processing!
In [3]:
post_pr_days = len(dates_in_canada_post_pr)
pre_pr_days = len(dates_in_canada_pre_pr)
eligible_pre_pr_days = min(pre_pr_days, 365)
eligible_days = post_pr_days + eligible_pre_pr_days
eligibility_status = eligible_days > 1095

print(f'You have been in Canada for {post_pr_days} days since becoming a permanent resident and {pre_pr_days} days before becoming a permanent resident and within 5 years.')
print(f'You are eligible for an additional {eligible_pre_pr_days} pre permanent resident days.')
print(f'Your total eligible days in Canada is {eligible_days}')
print('Eligiblity status: ' + ('eh+' if eligibility_status else 'n/eh'))
You have been in Canada for 764 days since becoming a permanent resident and 506 days before becoming a permanent resident and within 5 years.
You are eligible for an additional 365 pre permanent resident days.
Your total eligible days in Canada is 1129
Eligiblity status: eh+