datetime module#

Conversion of datetime formats

The module enhances cftime by non-CF date formats.

This module was written by Matthias Cuntz while at Institut National de Recherche pour l’Agriculture, l’Alimentation et l’Environnement (INRAE), Nancy, France.

copyright:

Copyright 2022- Matthias Cuntz, see AUTHORS.rst for details.

license:

MIT License, see LICENSE for details.

The following functions are provided:

date2dec(*args, **kwargs)

Wrapper for date2num()

date2num(dates[, units, calendar, ...])

Return numeric time values given datetime objects or strings

dec2date(*args, **kwargs)

Wrapper for num2date()

num2date(times[, units, calendar, ...])

Return datetime objects given numeric time values

datetime(year, month, day[, hour, minute, ...])

This class mimics cftime.datetime but for non-CF-conform calendars

History
  • Written date2dec and dec2date Jun 2010, Arndt Piayda

  • Input can be scalar or array_like, Feb 2012, Matthias Cuntz

  • fulldate=True default in dec2date, Feb 2012, Matthias Cuntz

  • Added calendars decimal and decimal360, Feb 2012, Matthias Cuntz

  • Rename units to refdate and add units as in netcdftime in dec2date, Jun 2012, Matthias Cuntz

  • Add units=’day as %Y%m%d.%f’ in dec2date, Jun 2012, Matthias Cuntz

  • Change units of proleptic_gregorian from ‘days since 0001-01-01 00:00:00’ to ‘days since 0001-01-00 00:00:00’ in date2dec, Dec 2012, Matthias Cuntz

  • Bug in Excel and leap years, Feb 2013

  • Ported to Python 3, Feb 2013

  • Bug in ‘eng’ output of dec2date, May 2013, Arndt Piayda

  • Times with keywords ascii and eng default to 00:00:00 in date2dec, Jul 2013, Matthias Cuntz

  • Corrected that Excel year starts as 1 not at 0, Oct 2013, Matthias Cuntz

  • But in units keyword and Julian calendar, day was subtracted even if units were given, Oct 2013, Matthias Cuntz

  • Removed remnant of time treatment before time check in eng keyword in date2dec, Nov 2013, Matthias Cuntz

  • Adapted date2dec to new netCDF4/netcdftime (>=v1.0) and Python datetime (>v2.7.9), Jun 2015, Matthias Cuntz

  • Add units==’month as %Y%m.%f’ and units==’year as %Y.%f’ in dec2date, May 2016, Matthias Cuntz

  • Now possible to pass array_like to date2num instead of single netCDF4.datetime objects in date2dec, Oct 2016, Matthias Cuntz

  • Provide netcdftime even with netCDF4 > v1.0.0, Oct 2016, Matthias Cuntz

  • mo is always integer in date2dec, Oct 2016, Matthias Cuntz

  • leap is always integer in dec2date, Oct 2016, Matthias Cuntz

  • Corrected 00, 01, etc. in date2dec, which are not accepted as integer constants by Python 3, Nov 2016, Matthias Cuntz

  • numpydoc docstring format, May 2020, Matthias Cuntz

  • Renamed eng keword to en, Jul 2020, Matthias Cuntz

  • Use proleptic_gregorian calendar for Excel dates, Jul 2020, Matthias Cuntz

  • Change all np.int, np.float, etc. to Python equivalents, May 2021, Matthias Cuntz

  • flake8 compatible, May 2021, Matthias Cuntz

  • Written class_datetime, Jun 2022, Matthias Cuntz Complete rewrite from scratch following closely cftime but for non-CF-conform calendars such as decimal, Excel, and the cdo absolute time formats (e.g. units=’day as %Y%m%d.%f’). Provides its own datetime class. Use cftime notation now, i.e. date2num and num2date but provide date2dec and dec2date wrappers for backward compatibility (almost). Provide microsecond resolution with all supported calendars no matter of the units, which means that date2num returns np.longdouble values. date2num works together with date2date and can have formatted date strings as input.

  • calendar keyword takes precedence on calendar attribute of datetime objects in date2num, Jul 2022, Matthias Cuntz

  • return_arrays keyword in date2num, Jul 2022, Matthias Cuntz

  • round_microseconds method for datetime, Jul 2022, Matthias Cuntz

  • only_use_pyjams_datetimes keyword in num2date, Jan 2022, Matthias Cuntz

  • Also CF-calendars in datetime class, Jan 2023, Matthias Cuntz

  • Use longdouble keyword with date2num if cftime > v1.6.1, Aug 2024, Matthias Cuntz

  • Filter UserWarning from cftime, Aug 2024, Matthias Cuntz

  • ensure_seconds keyword in date2num, Aug 2024, Matthias Cuntz

ToDo
  • Check why datetime + timedelta but not timedelta + datetime

  • add date2index

  • add time2index

  • implement fromordinal

  • implement change_calendar

  • strptime

class datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, dayofwk=-1, dayofyr=-1, calendar='decimal', has_year_zero=None)[source]#

Bases: object

This class mimics cftime.datetime but for non-CF-conform calendars

The cftime.datetime class mimics itself datetime.datetime but supports calendars other than the proleptic Gregorian calendar.

This class supports timedelta operations by overloading +/-, and comparisons with other instances using the same calendar.

Current supported calendars are excel, excel1900, excel1904, and decimal, decimal360, decimal365, decimal366. Excel calendars are supposedly Julian calendars with other reference dates. Day 0 of excel/excel1900 starts at 1899-12-31 00:00:00 and day 0 of excel1904 (old Lotus date) starts at 1903-12-31 00:00:00. Decimal calendars have the form “%Y.%f”, where the fractional year assumes leap years as the proleptic Gregorian calendar, or fixed 360, 365, or 366 days per year.

If the has_year_zero keyword argument is set to True, astronomical year numbering is used and the year zero exists, which is the default for the decimal calendars. The keyword will be ignored for Excel calendars.

The class has the methods isoformat, strftime, timetuple, replace, dayofwk, dayofyr, daysinmonth, __repr__, __format__, __add__, __sub__, __str__, and comparison methods.

The default format of the string produced by strftime is controlled by self.format (default %Y-%m-%d %H:%M:%S).

Methods

assert_valid_date()

Check that datetime is a valid date for given calendar

dayofwk()

Day of the week

dayofyr()

Day of year

daysinmonth()

Number of days in current month

format()

Standard date representation

isoformat([sep, timespec])

ISO date representation

replace(**kwargs)

Return datetime with new specified fields

round_microseconds()

Mathematically round microseconds to nearest second.

strftime([format])

Return a string representing the date, controlled by an explicit format string

timetuple()

Return a time.struct_time such as returned by time.localtime()

to_tuple()

Turn a datetime instance into a tuple of integers.

toordinal([fractional])

Julian day (integer) ordinal

change_calendar

fromordinal

assert_valid_date()[source]#

Check that datetime is a valid date for given calendar

change_calendar(calendar, has_year_zero=None)[source]#
dayofwk()[source]#

Day of the week

Identical to cftime.datetime

dayofyr()[source]#

Day of year

daysinmonth()[source]#

Number of days in current month

format()[source]#

Standard date representation

Identical to cftime.datetime

fromordinal(calendar='decimal', has_year_zero=None)[source]#
isoformat(sep='T', timespec='auto')[source]#

ISO date representation

replace(**kwargs)[source]#

Return datetime with new specified fields

Identical to cftime.datetime

round_microseconds()[source]#

Mathematically round microseconds to nearest second.

strftime(format=None)[source]#

Return a string representing the date, controlled by an explicit format string

For a complete list of formatting directives, see section ‘strftime() and strptime() Behavior’ in the base Python documentation.

Identical to cftime.datetime

timetuple()[source]#

Return a time.struct_time such as returned by time.localtime()

The DST flag is -1. d.timetuple() is equivalent to time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst)), where yday is the day number within the current year starting with 1 for January 1st.

Identical to cftime.datetime

to_tuple()[source]#

Turn a datetime instance into a tuple of integers. Elements go in the order of decreasing significance, making it easy to compare datetime instances. Parts of the state that don’t affect ordering are omitted. to_tuple(dt) is identical to (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond). Compare to timetuple().

Identical to cftime.datetime

toordinal(fractional=False)[source]#

Julian day (integer) ordinal

Day 0 starts at noon January 1 of the year -4713 for the Excel calendars.

Day 0 starts at noon on January 1 of the year zero for the decimal calendars.

If fractional=True, fractional part of day is included (default False).

date2dec(*args, **kwargs)[source]#

Wrapper for date2num()

date2num(dates, units='', calendar=None, has_year_zero=None, format='', timesep=' ', fr=False, return_arrays=False, ensure_seconds=False)[source]#

Return numeric time values given datetime objects or strings

The units of the numeric time values are described by the units and calendar keywords for CF-conform calendars, i.e. standard, gregorian, julian, proleptic_gregorian, 360_day, 365_day, 366_day, noleap, all_leap. See http://cfconventions.org/cf-conventions/cf-conventions#calendar These times will be passed to cftime.num2date.

Standard units are used for the non-CF-conform calendars excel, excel1900, excel1904, and decimal, decimal360, decimal365, decimal366, and given units will hence be ignored.

Parameters:
  • dates (datetime instance or str, or array_like of datetime or str) – datetime objects or strings with string representations. datetime objects can either be Python datetime.datetime, cf.datetime, or pyjams.datetime objects. If dates are strings, then format keyword is relevant.

  • units (str, optional) –

    Units string such as ‘seconds since 1900-01-01 00:00:00’ or ‘day as %Y%m%d.%f’. Standard units corresponding to days after day 0 of a given calendar will be used if omitted, i.e. assuming Julian day ordinals.

    In the form time_units since reference_time, time_units can be days, hours, minutes, seconds, milliseconds, or microseconds. reference_time is the time origin. months since is allowed only for the 360_day calendar and common_years since is allowed only for the 365_day calendar.

    There are currently only three valid forms for time_units as format: ‘day as %Y%m%d.%f’, ‘month as %Y%m.%f’, ‘year as %Y.%f’. The latter is the same as ‘calendar=decimal’. calendar=’decimal’ will be set in case units *time_units as format.

  • calendar (str, optional) – One of the supported calendars, i.e. the CF-conform calendars standard, gregorian, julian, proleptic_gregorian, 360_day, 365_day, 366_day, noleap, all_leap, as well as the non-CF-conform calendars excel, excel1900, excel1904, and decimal, decimal360, decimal365, decimal366. standard will be taken by default, which is a mixed Julian/Gregorian calendar. The keyword takes precedence on calendar in datetime objects.

  • has_year_zero (bool, optional) – Astronomical year numbering is used and the year zero exists, if set to True. If set to False for real-world calendars, then historical year numbering is used and the year 1 is preceded by year -1 and no year zero exists. The defaults are set to conform with CF version 1.9 conventions, i.e. False for ‘standard’, ‘gregorian’, and ‘julian’, True for ‘proleptic_gregorian’ (ISO 8601), and True for the idealized calendars ‘noleap’/’365_day’, ‘360_day’, 366_day’/’all_leap’. Excel calendars excel, excel1900, excel1904 start only 1900 or above so has_year_zero is always False. Decimal calendars decimal, decimal360, decimal365, decimal366 have always year 0, i.e. has_year_zero is True.

  • format (str, optional) – If dates are strings, then format is the Python datetime.strftime/strptime format string if given. If empty (default), then the routine pyjams.date2date will be used, which converts between formats ‘%Y-%m-%d %H:%M:%S’, ‘%d.%m.%Y %H:%M:%S’, and ‘%m/%d/%Y %H:%M:%S’ (called English YYYY-MM-DD hh:mm:ss, standard DD.MM.YYYY hh:mm:ss, and American MM/DD/YYYY hh:mm:ss in pyjams.date2date), where times can be partial or missing.

  • timesep (str, optional) – Separator string between date and time used by pyjams.date2date if if dates are strings and format is empty (default: ‘ ‘)

  • fr (bool, optional) – If True, pyjams.date2date will interpret input dates with ‘/’ separators not as the American format ‘%m/%d/%Y %H:%M:%S’ but the French way as ‘%d/%m/%Y %H:%M:%S’, if dates are strings and format is empty

  • return_arrays (bool, optional) – If True, then return a tuple with individual arrays for year, month, day, hour, minute, second, microsecond

  • ensure_seconds (bool, optional) –

    If True, add small number (< 20 microseconds) to results to ensure that back-conversion (num2date) gives the same results up to seconds.

    Results should have an accuracy of approximately 1 microseconds. This is however only possible with 64-bits if the discretization of the time variable is an integer multiple of the units. cftime introduced the longdouble keyword in cftime.date2num to get microseconds accuracy. The datatype is, however, not available on all platforms. The algorithm has the tendency to give 1-3 microseconds less at back-conversion in this case, which gives times such as “11:59:59” instead of “12:00:00”. ensure_seconds toggles back-conversion above the next second to ensure that the seconds are correct.

Returns:

numeric time values

Return type:

array_like

Examples

>>> idates = ['2000-01-05 12:30:15', '1810-04-24 16:15:10',
...           '1630-07-15 10:20:40', '1510-09-20 14:35:50',
...           '1271-03-18 19:41:34', '0619-08-27 11:08:37',
...           '0001-01-01 12:00:00']
>>> decimal = date2num(idates, calendar='decimal')
>>> num2date(decimal, calendar='decimal', format='%Y-%m-%d %H:%M:%S')
['2000-01-05 12:30:15',
 '1810-04-24 16:15:10',
 '1630-07-15 10:20:40',
 '1510-09-20 14:35:50',
 '1271-03-18 19:41:34',
 '0619-08-27 11:08:37',
 '0001-01-01 12:00:00']
dec2date(*args, **kwargs)[source]#

Wrapper for num2date()

num2date(times, units='', calendar='standard', only_use_pyjams_datetimes=True, only_use_cftime_datetimes=True, only_use_python_datetimes=False, has_year_zero=None, format='', return_arrays=False)[source]#

Return datetime objects given numeric time values

The units of the numeric time values are described by the units and calendar keywords for CF-conform calendars, i.e. standard, gregorian, julian, proleptic_gregorian, 360_day, 365_day, 366_day, noleap, all_leap. See http://cfconventions.org/cf-conventions/cf-conventions#calendar These times will be passed to cftime.num2date.

Standard units are used for the non-CF-conform calendars excel, excel1900, excel1904, and decimal, decimal360, decimal365, decimal366, and given units will hence be ignored.

Parameters:
  • times (float or array_like) – Numeric time values

  • units (str, optional) –

    Units string such as ‘seconds since 1900-01-01 00:00:00’ or ‘day as %Y%m%d.%f’. Standard units corresponding to days after day 0 of a given calendar will be used if omitted, i.e. assuming Julian day ordinals.

    In the form time_units since reference_time, time_units can be days, hours, minutes, seconds, milliseconds, or microseconds. reference_time is the time origin. months since is allowed only for the 360_day calendar and common_years since is allowed only for the 365_day calendar.

    There are currently only three valid forms for time_units as format: ‘day as %Y%m%d.%f’, ‘month as %Y%m.%f’, ‘year as %Y.%f’. The latter is the same as ‘calendar=decimal’. calendar=’decimal’ will be set in case units *time_units as format.

  • calendar (str, optional) – One of the support calendars, i.e. the CF-conform calendars standard, gregorian, julian, proleptic_gregorian, 360_day, 365_day, 366_day, noleap, all_leap, as well as the non-CF-conform calendars excel, excel1900, excel1904, and decimal, decimal360, decimal365, decimal366. standard will be taken by default, which is a mixed Julian/Gregorian calendar.

  • only_use_pyjams_datetimes (bool, optional) – pyjams.datetime objects are returned by default. Only if only_use_pyjams_datetimes is set to False (default: True) and only_use_cftime_datetimes is set to True then cftime.datetime objects will be returned where possible. Only if only_use_pyjams_datetimes and only_use_cftime_datetimes are set to False and only_use_python_datetimes is set to True then Python datetime.datetime objects will be returned where possible.

  • only_use_cftime_datetimes (bool, optional) – pyjams.datetime objects are returned by default. Only if only_use_pyjams_datetimes is set to False and only_use_cftime_datetimes is set to True (default: False) then cftime.datetime objects will be returned where possible. Only if only_use_pyjams_datetimes and only_use_cftime_datetimes are set to False and only_use_python_datetimes is set to True then Python datetime.datetime objects will be returned where possible.

  • only_use_python_datetimes (bool, optional) – pyjams.datetime objects are returned by default. Only if only_use_pyjams_datetimes is set to False and only_use_cftime_datetimes is set to True then cftime.datetime objects will be returned where possible. Only if only_use_pyjams_datetimes and only_use_cftime_datetimes are set to False and only_use_python_datetimes is set to True (default: False) then Python datetime.datetime objects will be returned where possible.

  • has_year_zero (bool, optional) – Astronomical year numbering is used and the year zero exists, if set to True. If set to False for real-world calendars, then historical year numbering is used and the year 1 is preceded by year -1 and no year zero exists. The defaults are set to conform with CF version 1.9 conventions, i.e. False for ‘standard’, ‘gregorian’, and ‘julian’, True for ‘proleptic_gregorian’ (ISO 8601), and True for the idealized calendars ‘noleap’/’365_day’, ‘360_day’, 366_day’/’all_leap’. Excel calendars excel, excel1900, excel1904 start only 1900 or above so has_year_zero is always False. Decimal calendars decimal, decimal360, decimal365, decimal366 have always year 0, i.e. has_year_zero is True.

  • format (str, optional) – If format string is given than a string representation of the datetime objects will be returned.

  • return_arrays (bool, optional) – If True, then return a tuple with individual arrays for year, month, day, hour, minute, second, microsecond

Returns:

datetime instances or string representations of datetime objects, or tuple with individual arrays for year, month, day, hour, minute, second, microsecond

Return type:

array_like

Examples

>>> idates = ['2000-01-05 12:30:15', '1810-04-24 16:15:10',
...           '1630-07-15 10:20:40', '1510-09-20 14:35:50',
...           '1271-03-18 19:41:34', '0619-08-27 11:08:37',
...           '0001-01-01 12:00:00']
>>> decimal = date2num(idates, calendar='decimal')
>>> num2date(decimal, calendar='decimal', format='%Y-%m-%d %H:%M:%S')
['2000-01-05 12:30:15',
 '1810-04-24 16:15:10',
 '1630-07-15 10:20:40',
 '1510-09-20 14:35:50',
 '1271-03-18 19:41:34',
 '0619-08-27 11:08:37',
 '0001-01-01 12:00:00']