Pendulum is more than just a datetime library, it's also an efficient timezone library.
In Python, when you think about timezone handling you usually think pytz
which
is a useful library. However it is pretty slow, especially to localize and normalize naive datetime
(it's less clear when localizing timezone-aware datetimes since both libraries rely
on standard datetime operations.).
It also has some bugs that have not been fixed in quite some time (as you can see on its bug tracker https://bugs.launchpad.net/pytz).
So, Pendulum brings its own, more efficient, timezone library with a more intuitive API (you only need to use the convert()
method).
Benchmarks
Each benchmark was done for Python 2.7, PyPy and Python 3.5. timeit
was used with the default of 1 million executions per benchmark and the best of 3 repeats was picked.
Normalize and localize a naive datetime
The setup for the benchmark is the following:
import pytz
import pendulum
from datetime import datetime
dt = datetime(2013, 3, 31, 2, 30)
t1 = pytz.timezone('Europe/Paris')
t2 = pendulum.timezone('Europe/Paris')
The code executed for pytz
:
t1.normalize(t1.localize(dt))
The code executed for pendulum
:
t2.convert(dt)
The results:
Both libraries return a properly localized and normalized datetime
object:
>>> t1.normalize(t1.localize(dt)).isoformat()
'2013-03-31T03:30:00+02:00'
>>> t2.convert(dt).isoformat()
'2013-03-31T03:30:00+02:00'
Normalize and localize a timezone-aware datetime
The setup for the benchmark is the following:
import pytz
import pendulum
from datetime import datetime
dt = datetime(2013, 3, 31, 2, 30)
t1 = pytz.timezone('Europe/Paris')
t2 = pendulum.timezone('Europe/Paris')
t3 = pytz.timezone('America/New_York')
t4 = pendulum.timezone('America/New_York')
loc1 = t1.normalize(t1.localize(dt))
loc2 = t2.convert(dt)
The code executed for pytz
:
loc1.astimezone(t3)
The code executed for pendulum
:
t4.convert(loc2)
The results:
Both libraries return the proper datetime
object in the new timezone:
>>> loc1.astimezone(t3).isoformat()
'2013-03-30T21:30:00-04:00'
>>> t4.convert(loc2).isoformat()
'2013-03-30T21:30:00-04:00'
A quick comparison
Here are some examples where pytz
will behave strangely:
Another example:
>>> pytz.timezone('Africa/Abidjan').localize(datetime(year=1, month=1, day=1))
# OverflowError: date value out of range
>>> pytz.timezone('Africa/Abidjan').localize(datetime(year=9999, month=12, day=31))
# OverflowError: date value out of range
With pendulum
:
>>> timezone('Africa/Abidjan').convert(datetime(year=1, month=1, day=1))
# datetime.datetime(1, 1, 1, 0, 0, tzinfo=<TimezoneInfo [Africa/Abidjan, LMT, -1:43:52, STD]>)
>>> timezone('Africa/Abidjan').convert(datetime(year=9999, month=12, day=31))
# datetime.datetime(9999, 12, 31, 0, 0, tzinfo=<TimezoneInfo [Africa/Abidjan, GMT, +00:00:00, STD]>)