Time#

Overview#

This section covers NCL functions relating to dates and times:

day_of_week#

NCL’s day_of_week calculates the day of the week given month, day, and year.

Grab and Go#

import cftime

day = 4
month = 6
year = 2024

dow = cftime.datetime(
    year, month, day, calendar='proleptic_gregorian', has_year_zero=True
).strftime("%w")
print(dow)
2

Using the datetime module#

The datetime module is part of the Python Standard Library and could be sufficient to calculate the day of the week.

import datetime

day = 4
month = 6
year = 2024

dow = datetime.date(year, month, day).strftime('%A')
print(f"{year}-{month}-{day} is a {dow}")
2024-6-4 is a Tuesday

However, the datetime module does not support year 0. If you need to work with year 0, we suggest using cftime.

The datetime module also only uses the proleptic Gregorian calendar. If you need to work with other calendars, we suggest using cftime.

Using cftime#

cftime offers a solution to these potential issues by supporting year 0 and all of the CF Convention calendars. Here is how you can use cftime to calculate the day of the week.

import cftime

day = 4
month = 6
year = 2024

dow = cftime.datetime(
    year, month, day, calendar='proleptic_gregorian', has_year_zero=True
).strftime('%A')
print(f"Proleptic Gregorian calendar: \t\t{year}-{month}-{day} is a {dow}")

dow = cftime.datetime(
    year, month, day, calendar='standard', has_year_zero=True
).strftime('%A')
print(f"Standard calendar: \t\t\t{year}-{month}-{day} is a {dow}")

dow = cftime.datetime(year, month, day, calendar='julian', has_year_zero=True).strftime(
    '%A'
)
print(f"Julian calendar: \t\t\t{year}-{month}-{day} is a {dow}")

dow = cftime.datetime(
    year, month, day, calendar='360_day', has_year_zero=True
).strftime('%A')
print(f"360 day calendar: \t\t\t{year}-{month}-{day} is a {dow}")
Proleptic Gregorian calendar: 		2024-6-4 is a Tuesday
Standard calendar: 			2024-6-4 is a Tuesday
Julian calendar: 			2024-6-4 is a Monday
360 day calendar: 			2024-6-4 is a Wednesday

Using the strftime() method allows you to format the output of cftime.datetime. If you desire an output equivalent to that of NCL’s day_of_week, we suggest using .strftime('%w').

Differences between cftime and NCL’s day_of_week#

Calendars#

NCL’s day_of_week only supports the proleptic Gregorian calendar, while the cftime module supports all CF conventions calendars, including the proleptic_gregorian calendar.

Input Type#

Notably, using cftime to calculate the day of the week works by getting a strftime() value from a cftime.datetime object, which means that the calculations for the day of the week have to be collected through each date individually, while NCL’s days_in_month can take in multidimensional integer arrays, given that the year and month arrays have the same dimensions.

Year 0#

There is a slight difference in the way that NCL’s day_of_week and the cftime module handle the year 0.

  • NCL’s day_of_week supports all positive years and year 0 by default.

  • The cftime module supports all years, but handling for year 0 is dependent upon the calendar and/or the has_year_zero keyword argument.

days_in_month#

NCL’s days_in_month calculates the number of days in a month given a month and year.

Grab and Go#

import cftime

day = 1
month = 2
year = 2024

days = cftime.datetime(year, month, day, calendar='standard').daysinmonth

days
29

Using the calendar module#

The calendar module is part of the Python Standard Library and could be sufficient to calculate the number of days in a month.

from calendar import monthrange

month = 2
year = 1500
first_day, num_days = monthrange(year, month)
print(f"Month {month} in {year} has {num_days} days")
Month 2 in 1500 has 28 days

However, the calendar only uses a proleptic Gregorian calendar. If you need to work with other calendars, the calendar module will not be sufficient.

Using cftime#

cftime supports all of the CF Convention calendars. Here’s how you can use cftime to calculate the number of days in a month.

import cftime

day = 1
month = 2
year = 1500

days = cftime.datetime(year, month, day, calendar='standard').daysinmonth
print(f"standard calendar: \t\t\t\t month {month} in {year} has {days} days")

days = cftime.datetime(year, month, day, calendar='proleptic_gregorian').daysinmonth
print(f"proleptic Gregorian calendar: \t month {month} in {year} has {days} days")

days = cftime.datetime(year, month, day, calendar='julian').daysinmonth
print(f"Julian calendar: \t\t\t\t month {month} in {year} has {days} days")

days = cftime.datetime(year, month, day, calendar='360_day').daysinmonth
print(f"360 day calendar: \t\t\t\t month {month} in {year} has {days} days")
standard calendar: 				 month 2 in 1500 has 29 days
proleptic Gregorian calendar: 	 month 2 in 1500 has 28 days
Julian calendar: 				 month 2 in 1500 has 29 days
360 day calendar: 				 month 2 in 1500 has 30 days

Differences between cftime and NCL’s days_in_month#

Calendars#

The calendars available in cftime and NCL’s days_in_month, while both based on the CF Conventions calendars, are slightly different.

  • cftime does support using "none" as a calendar type, but not for this particular function.

  • NCL’s days_in_month does not support the proleptic_gregorian calendar.

Numerical Differences#

Additionally, the "standard" and "gregorian" calendars seem to disagree for some historical dates.

Input type#

Notably, using cftime to calculate the number of days in a month works by getting a daysinmonth value from a cftime.datetime object, which means that the calculations for days in a month have to be collected through each date individually, while NCL’s days_in_month can take in multidimensional integer arrays, given that the year and month arrays have the same dimensions.

Python Resources#