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 in you code (exceptions exist for libraries that check the type of the objects by using the
type function like
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' >>> (just_after.in_timezone('utc') - just_before.in_timezone('utc')).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.
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.