datetime2 — New date and time classes

The datetime2 module is intended to be a replacement of the datetime module. Its most visible feature is the ability to have multiple representation of the same date or time object. There are a few representations already available (see to Available date and time representations), but others can be ref:added at run time<interface>.

Each representation can be reached via the attribute paradigm, e.g.:

>>> d = Date(765432)
>>> print(d.gregorian)
2096-09-05
>>> print(d.iso)
2096-W36-3
>>> t = Time(0.25)
>>> print(t.western)
06:00:00
>>> print(t.internet)
@250

Representations do not consume memory unless they are effectively used. This is especially important for calendars, where many representation exists [1] .

Some long term objectives of the datetime2 module are:
  • internationalization;
  • implementation of the part of the Unicode Locale Database concerned with dates and times;
  • interface with other Python modules or inclusion of their functionalities in submodules.

Overview

The driving idea in the datetime2 is to detach operations on date or time from their representation in different cultures. After all, a day in history, or in future, is the same independently from the way it is represented, and the same is true also for time. Indeed, all base classes have a very simple definition of day and time.

This is a brief description of these four classes:

class datetime2.Date

An idealized date, with no notion of time or time zone. A date is defined counting the number of days elapsed from what would have been January 1st of year 1 on the Gregorian calendar. The only attribute of this class is: day_count.

class datetime2.Time

An indication of time, independent of any particular day. There might be a time correction, e.g. due to time zone or daylight saving time. Time and correction are stored as fraction of a day, using a Python fractions.Fraction. Attributes of this class are: day_frac, correction.

class datetime2.DateTime

A precise moment in time. There might be a time correction, e.g. due to time zone or daylight saving time. This class has not been implemented yet, but will interface with calendars and time representations used by the two classes above.

class datetime2.TimeDelta

A duration expressing the difference between two Date, Time, or DateTime instances. This difference is stored in a single Python fractions.Fraction. The only attribute of this class is: days.

datetime2 class names use the CapitalizedWords convention required by PEP 8, so they differ from the names of their similar counterparts in datetime module.

Currently (version 0.6.7) the following calendars and time representation are available:

See also

Module datetime
Basic date and time types.
Module calendar
General calendar related functions.
Module time
Time access and conversions.

Date Objects

A Date object represents a date in an idealized calendar, just counting the days elapsed from Gregorian Dec 31st of year 0, i.e. January 1st of year 1 is day number 1, January 2nd of year 1 is day number 2, and so on. This calendar ideally extends indefinitely in both directions. A Date object is printed as R.D. followed by the day count. R.D. stands for Rata Die, the Latin for “fixed date”.

There are two ways of creating a Date instance:

class datetime2.Date(day_count)

Return an object that represent a date which is day_count - 1 days after January 1 of year 1 in the current Gregorian calendar. The argument is required and must be an integer. There is no restriction on its numeric value.

classmethod Date.today()

Return a Date object that represents the current local date.

Date instances are immutable, so they can be used as dictionary keys. They can also be pickled and unpickled. In boolean contexts, all Date instances are considered to be true.

Date instances have one attribute:

Date.day_count

An integer that represents the number of days between the given date and January 1st, year 1. This attribute is read-only: an AttributeError exception is raised when trying to change it.

Date has one instance method:

Date.__str__()

Return R.D. followed by the day count. R.D. stands for Rata Die, the Latin for “fixed date”.

In addition, the following calendars are reachable via the listed access attributes:

Access attribute Calendar Calendar class Module
gregorian Gregorian GregorianCalendar datetime2.western
iso ISO IsoCalendar datetime2.modern

Supported operations

Operation Result
date2 = date1 + timedelta date2 is timedelta days after date1. Reverse addition (timedelta + date1) is also allowed. (1) (2)
date2 = date1 - timedelta date2 is timedelta days before date1. (1) (3)
timedelta = date1 - date2 A TimeDelta object is returned representing the number of days between date1 and date2. (4)
date1 < date2 date1 is less than date2 when it represents a day earlier that that of date2. (5) (6)

Notes:

  1. A ValueError exception is raised if timedelta is not an integral number of days. timedelta object with non-integral number of days must be added or subtracted from DateTime instances.
  2. If timedelta is negative, date2 will be before date1.
  3. If timedelta is negative, date2 will be after date1.
  4. A timedelta instance with with an integral number of dyas is always created when subtracting Date instances.
  5. In other words, date1 < date2 if and only if date1.day_count < date2.day_count. All other comparison operators (<=, >, >=, == and !=) behave similarly.
  6. Comparison between a Date object and an object of another class return a NotImplemented exception, except for the equality and inequality operators, which respectively return False and True.

Time Objects

An indication of time, independent of any particular day. There might be a time correction, e.g. due to time zone or daylight saving time. correction. This correction will be implemented in a future release, although it is still included in all Time signatures. If a Time object has a correction, it is said to be “aware” and is used to represent a precise moment in time. An object without correction is said to be “naive”, and ist interpretation is left to the program that uses it.

There are two ways of creating a Time instance:

class datetime2.Time(day_frac, *, correction=None)

Return an object that represent a moment in a day as a fraction of the whole day, given in the day_frac argument. If needed, a correction to this time, for whatever political, algorithmic or geographic need (e.g. time zone) can be given in hours and stored in the correction argument, which must be explicitly named.

In version 0.6, time correction is not implemented, although the constructor accepts it it.

The day_frac argument can be anything that can be passed to the fractions.Fraction constructor, i.e. an integer, a float, another Fraction, a Decimal number or a string representing an integer, a float or a fraction. It is also possible to use a 2-value tuple with integer values. This tuple represent the numerator and denominator of a fraction that will be passed to the fractions.Fraction constructor. In any case, the resulting value for day_frac must be equal or greater than 0 and less than 1. A TypeError exception is raised if the argument type is not one of the accepted types or the tuple argument does not have two values. A ZeroDivisionError exception is raised if denominator is 0.

classmethod Time.now(correction = None)

Return a Time object that represents the current moment in the day. It is possible to add a correction to this time.

In version 0.6, time correction is not implemented, although the constructor accepts it.

Time instances are immutable, so they can be used as dictionary keys. They can also be pickled and unpickled. In boolean contexts, all Time instances are considered to be true.

Time instances have two attributes:

Time.day_frac

A Python fractions.Fraction that represents the part of the day after midnight. This attribute is read-only: an AttributeError exception is raised when trying to change it.

Time.correction

A correction to the time of the day, in order to indicate a location and/or daylight saving time. In version 0.6, correction is not implemented, although the class accepts it.

Time has one instance method:

time.__str__()

Return the string <fraction> of a day, where fraction is the value of the day_frac attribute.

String representation of time correction will be defined in a future version.

In addition, the following time representation are reachable via the listed access attributes:

Attribute Representation Time representation class Module
western Western WesternTime datetime2.western
internet Internet InternetTime datetime2.modern

Supported operations

Operation Result
time2 = time1 + timedelta time2 is timedelta time after time1. Reverse addition (timedelta + time1) is also allowed. (1) (2)
time2 = time1 - timedelta time2 is timedelta time before time1. (1) (3)
timedelta = time1 - time2 A TimeDelta object is returned representing the day fraction between time1 and time2. (4)
time1 < time2 time1 is less than time2 when the former represents a moment earlier than the latter. (5) (6)

Notes:

  1. The result of this operation will always be a valid Time instance. If overflow or underflow occur, the full day part will be truncated so that only the fractional part will remain. If time1 has a correction, this will be copied to time2, so naivety is maintained.
  2. If timedelta is negative, time2 will be before time1.
  3. If timedelta is negative, time2 will be after time1.
  4. The timedelta object created when subtracting two Time instances will always represent a fractional part of a day, either positive or negative. time1 and time2 must have the same naivety; if they don’t, a ValueError exception is raised. If they are aware, correction of both instances will be taken into account to generate the result.
  5. All other comparison operators (<=, >, >=, == and !=) behave similarly. Both operand must have the same naivety; if they don’t, a ValueError exception is raised.
  6. Comparison between a Time object and an object of another class return a NotImplemented exception, except for the equality and inequality operators, which respectively return False and True.

Footnotes

[1]Well, this should be read as “will exist”, since current version(0.6.7) only has two of them.