Native datetime instances are enough for basic cases but when you face more complex use-cases they often show limitations and are not so intuitive to work with.
Pendulum provides a cleaner and easier to use API while still relying on the standard library. So it's still datetime but better.
Unlike other datetime libraries for Python, Pendulum is a drop-in replacement
for the standard datetime
class (it inherits from it), so, basically, you can replace all your
datetime
instances by DateTime
instances in you code (exceptions exist for libraries that check the type
of the objects by using the type
function like sqlite3
or PyMySQL
for
instance).
It also removes the notion of naive datetimes: each DateTime
instance is timezone-aware and by
default in UTC
for ease of use.
Pendulum also improves timedelta
by providing more intuitive methods and properties. See the documentation for more information.
Arrow is the most popular datetime library for Python right now, however its behavior
and API can be erratic and unpredictable. The get()
method can receive pretty much anything and
it will try its best to return something while silently failing to handle some cases:
>>> arrow.get('2016-1-17')
<Arrow [2016-01-01T00:00:00+00:00]>
>>> pendulum.parse('2016-1-17')
DateTime(2016, 1, 17, 0, 0, 0, tz='UTC')
>>> arrow.get('20160413')
<Arrow [1970-08-22T08:06:53+00:00]>
>>> pendulum.parse('20160413')
DateTime(2016, 4, 13, 0, 0, 0, tz='UTC')
>>> arrow.get('2016-W07-5')
<Arrow [1970-08-22T08:06:53+00:00]>
>>> pendulum.parse('2016-W07-5')
DateTime(2016, 2, 19, 0, 0, 0, tz='UTC')
# Working with DST
>>> just_before = arrow.Arrow(2013, 3, 31, 1, 59, 59, 999999, 'Europe/Paris')
>>> just_after = just_before.replace(microseconds=1)
'2013-03-31T02:00:00+02:00'
# Should be 2013-03-31T03:00:00+02:00
>>> (just_after.to('utc') - just_before.to('utc')).total_seconds()
-3599.999999
# Should be 1e-06
>>> just_before = pendulum.create(2013, 3, 31, 1, 59, 59, 999999, 'Europe/Paris')
>>> just_after = just_before.add(microseconds=1)
'2013-03-31T03:00:00+02:00'
>>> difference = just_after.in_timezone('utc') - just_before.in_timezone('utc')
>>> difference.total_seconds()
1e-06
Those are examples showing that Arrow cannot always be trusted to have a consistent behavior with the data you are passing to it.
Here are multiple performance benchmarks. The other libraries used for these benchmarks are Arrow and Delorean
Creation of 10000 objects via the default constructor.
Creation of 10000 objects representing the current time.
Changing the timezone 10000 times.
Casting an instance to string 10000 times.
Creating an instance from a string 10000 times.
Formatting an instance to a string 10000 times.
Creating an instance from a timestamp 10000 times.