Pendulum 0.7.0 is now out.

It is the biggest release yet and brings a lot of new features, bug fixes, deprecations and small API changes.

For the full list of changes, see the Change Log

New Features

A new Date class

Just like the Pendulum class is a drop-in replacement for the standard datetime class, the Date class is a replacement for the date class.

Every method of the standard class are accessible and new methods and attributes have been added.

Check out the documentation for more information.

A new Time class

The Time class is a replacement for the time class of the standard library.

Every method of the standard class are accessible and new methods and attributes have been added.

Check out the documentation for more information.

Experimental support of the fold attribute

The fold attribute for datetime objects has been introduced in Python 3.6 and aims at simplifying the disambiguation of repeated times.

pendulum adds the support of the fold attribute when instantiating a Pendulum instance and when using the timezone library on datetime objects holding the attribute.

>>> from pendulum import Pendulum

>>> dt = Pendulum(2013, 10, 27, 2, 30, tzinfo='Europe/Paris', fold=0)
>>> dt.isoformat()
'2013-10-27T02:30:00+02:00'

>>> dt = Pendulum(2013, 10, 27, 2, 30, tzinfo='Europe/Paris', fold=1)
>>> dt.isoformat()
'2013-10-27T02:30:00+01:00'

In Python 3.6+, when using convert(), the value of the fold attribute will be used to determine the transition rule. So the behavior will be slightly different compared to previous versions.

>>> from datetime import datetime
>>> from pendulum import timezone

>>> paris = timezone('Europe/Paris')
>>> dt = datetime(2013, 3, 31, 2, 30)
# By default, fold is set to 0
>>> dt = paris.convert(dt)
>>> dt.isoformat()
'2013-03-31T02:30:00+01:00'

>>> dt = datetime(2013, 3, 31, 2, 30, fold=1)
>>> dt = paris.convert(dt)
>>> dt.isoformat()
'2013-03-31T03:30:00+02:00'

You can override this behavior by explicitely passing the transition rule to convert().

>>> paris = timezone('Europe/Paris')
>>> dt = datetime(2013, 3, 31, 2, 30)
>>> dt = paris.convert(dt, dst_rule=paris.POST_TRANSITION)
>>> dt.isoformat()
'2013-03-31T03:30:00+02:00'

Other new features

  • Added a remaining_days property to the Interval class.

    >>> import pendulum
    
    >>> it = pendulum.interval(days=1177, seconds=7284, microseconds=1234)
    
    # The remaining days not included in full weeks
    >>> it.remaining_days
    1
    >>> it.days
    1117
    
  • Added a int_timestamp property to the Pendulum class to retrieve the behavior of the now deprecated timestamp property.

    import pendulum
    
    >>> dt = pendulum.parse('2012-09-05 23:26:11.123789')
    >>> dt.int_timestamp
    1346887571
    
  • start_of()/end_of() now supports hour, minute and second units.

    >>> import pendulum
    
    >>> dt = pendulum.create(2016, 11, 26, 12, 34, 56, 123456)
    >>> dt.start_of('hour').isoformat()
    '2016-11-26T12:00:00+00:00'
    >>> dt.end_of('hour').isoformat()
    '2016-11-26T12:59:59.999999+00:00'
    >>> dt.start_of('minute').isoformat()
    '2016-11-26T12:34:00+00:00'
    >>> dt.end_of('minute').isoformat()
    '2016-11-26T12:34:59.999999+00:00'
    >>> dt.start_of('second').isoformat()
    '2016-11-26T12:34:56+00:00'
    >>> dt.end_of('second').isoformat()
    '2016-11-26T12:34:56.999999+00:00'
    
  • astimezone() now supports timezone strings.

    >>> import pendulum
    
    >>> dt = pendulum.create(2016, 11, 26, 1, tz='Europe/Paris')
    >>> dt.isoformat()
    '2016-11-26T01:00:00+01:00'
    >>> dt = dt.astimezone('America/New_York')
    >>> dt.isoformat()
    '2016-11-25T19:00:00-05:00'
    
  • Interval.in_words() now displays subseconds when no other units are available.

    >>> import pendulum
    
    >>> it = pendulum.interval(microseconds=123456)
    >>> it.in_words()
    '0.12 second'
    

Changes

  • Period properties (especially years and months) are now accurate.
  • Interval.seconds now returns the whole number of remaining seconds, like timedelta, for compatibility. Use remaining_seconds to get the previous behavior back.
  • Improved parsing performances for common formats.
  • The library no longer relies on pytz. It now depends on pytzdata for its timezone database.
  • Locale, test instance and formatter are now set globally at the module level when using the corresponding module methods.
  • Performance improvements when parsing common formats.

Deprecations

  • timestamp should now be used as a method and no longer as a property. It will be a native method in the next major version.

    >>> import pendulum
    
    >>> dt = pendulum.now()
    >>> dt.timestamp
    # This notation should no longer be used.
    # instead use int_timestamp
    >>> dt.int_timestamp
    >>> dt.timestamp()
    # It will return a float timestamp
    # just like the standard library
    # You can still use float_timestamp
    >>> dt.float_timestamp
    
  • Interval properties and methods related to years and months are now deprecated.

  • Interval.days_exclude_weeks is now deprecated. Use remaining_days instead.

Fixes

  • Exception when loading specific timezones has been fixed.
  • end_of('day') now properly sets microseconds to 999999.
  • Accuracy of Period instances properties has been improved.
  • Accuracy for microseconds when initializing a Pendulum instance in some timezones has been fixed.
  • Periods are now serializable with pickle.
  • Fixed minute_(), second_() and microsecond_() setters changing the hour unit.
  • Fixed Windows support.