The new major version of Pendulum is finally out!

A lot has been modified, both internally and public API wise, and as such this version is not backwards compatible with the 1.x branch.

It tries to be closer to the standard library than previous versions. An example of this is that the constructor no longer accept anything else than tzinfo objects. This is why as of this version the datetime() helper must always be preferred over the standard constructor.

New Features

years and months support for durations

Durations (previously intervals) now support specifying years and months.

>>> import pendulum
>>> dur = pendulum.duration(years=2, months=3)
>>> dt = pendulum.datetime(2015, 3, 14)
>>> dt2 = dt + dur
>>> print(dt2)
'2017-06-14T00:00:00+00:00'

To maintain compatibility, native methods and properties will make approximations when years and months have been specified:

>>> dur.days
820
>>> dur.total_seconds()
70848000.0

Support for ISO 8601 duration and interval parsing

Pendulum now support parsing ISO 8601 duration and interval strings.

>>> import pendulum

>>> pendulum.parse('P1Y2M10DT2H30M')
Duration(years=1, months=2, weeks=1, days=3, hours=2, minutes=30)

>>> pendulum.parse('2007-03-01T13:00:00Z/2008-05-11T15:30:00Z')
<Period ['2007-03-01T13:00:00+00:00' -> '2008-05-11T15:30:00+00:00']>

>>> pendulum.parse('2008-05-11T15:30:00Z/P1Y2M10DT2H30M')
<Period ['2008-05-11T15:30:00+00:00' -> '2009-07-21T18:00:00+00:00']>

>>> pendulum.parse('P1Y2M10DT2H30M/2008-05-11T15:30:00Z')
<Period ['2007-03-01T13:00:00+00:00' -> '2008-05-11T15:30:00+00:00']>

Support for POSIX TZ specification for timezones

Pendulum now supports the POSIX TZ specification in tzinfo files to determine the DST transitions beyond the year 2038.

Let's take an example. In Pendulum v1, datetimes beyond year 2038 would take the DST information of the last transition.

>>> import pendulum
>>> dt = pendulum.datetime(2134, 3, 28, 2, 30, tz='Europe/Paris')
>>> print(dt)
'2134-03-28T02:30:00+01:00'

Now, it will return the proper DST information.

>>> import pendulum
>>> dt = pendulum.datetime(2134, 3, 28, 2, 30, tz='Europe/Paris')
>>> print(dt)
'2134-03-28T03:30:00+02:00'

Changes

Class names changes

The Pendulum class has been renamed to DateTime and the Interval class has been renamed to Duration.

create() has been removed

The create() helper has been removed in favor of datetime().

Keywords changes for parse()

The strict keyword in parse(), which initially controlled the type returned by the helper and since replaced by the exact keyword, now control the strictness of accepted strings.

Basically, strict=True means that pendulum will not fallback on the dateutil parser if it's unable to recognize the string.

format() and from_format() now only support one formatter

The previously named alternative formatter is now the only one supported in both format() and from_format() methods.

>>> import pendulum
>>> dt = pendulum.datetime(1975, 12, 25, 14, 15, 16)
>>> dt.format('YYYY-MM-DD HH:mm:ss')
'1975-12-25 14:15:16'
>>> dt = pendulum.from_format('1975-05-21 22', 'YYYY-MM-DD HH')
>>> print(dt)
'1975-05-21T22:00:00+00:00'

at() now supports setting partial time

The at() method now supports setting partial time. 

>>> import pendulum
>>> dt = pendulum.datetime(2018, 1, 15)
>>> print(dt.at(10))
'2018-01-15T10:00:00+00:00'
>>> print(dt.at(11, 30))
'2018-01-15T11:30:00+00:00'

diff_for_humans() improvements

The diff_for_humans() method now returns a few seconds when the difference in seconds is less than a threshold.

>>> import pendulum
>>> pendulum.now().diff_for_humans()
'a few seconds ago'

Other changes

  • local, utc and is_dst are now methods rather than properties (is_local(), is_utc(), is_dst()).
  • Changed the repr of most common objects.
  • Improved performances of the precise_diff() helper.
  • set_to_string_format()/reset_to_string_format() methods have been removed.
  • Removed xrange() method of the Period class and made range() a generator.
  • New locale system which uses CLDR data for most of the translations.