Skip to main content

Python datetimes made easy.

Project description

https://img.shields.io/pypi/v/pendulum.svg https://img.shields.io/pypi/l/pendulum.svg https://img.shields.io/codecov/c/github/sdispater/pendulum/master.svg Pendulum Build status

Python datetimes made easy.

Supports Python 2.7+, 3.2+ and PyPy.

>>> import pendulum

>>> now_in_paris = pendulum.now('Europe/Paris')
>>> now_in_paris
'2016-07-04T00:49:58.502116+02:00'

# Seamless timezone switching
>>> now_in_paris.in_timezone('UTC')
'2016-07-03T22:49:58.502116+00:00'

>>> tomorrow = pendulum.now().add(days=1)
>>> last_week = pendulum.now().subtract(weeks=1)

>>> if pendulum.now().is_weekend():
...     print('Party!')
'Party!'

>>> past = pendulum.now().subtract(minutes=2)
>>> past.diff_for_humans()
>>> '2 minutes ago'

>>> delta = past - last_week
>>> delta.hours
23
>>> delta.in_words(locale='en')
'6 days 23 hours 58 minutes'

# Proper handling of datetime normalization
>>> pendulum.create(2013, 3, 31, 2, 30, 0, 0, 'Europe/Paris')
'2013-03-31T03:30:00+02:00' # 2:30 does not exist (Skipped time)

# Proper handling of dst transitions
>>> just_before = pendulum.create(2013, 3, 31, 1, 59, 59, 999999, 'Europe/Paris')
'2013-03-31T01:59:59.999999+01:00'
>>> just_before.add(microseconds=1)
'2013-03-31T03:00:00+02:00'

Why Pendulum?

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 more easy 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 Pendulum 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 Pendulum instance is timezone-aware and by default in UTC for ease of use.

Pendulum also improves the standard timedelta class by providing more intuitive methods and properties.

Why not Arrow?

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')
# <Pendulum [2016-01-17T00:00:00+00:00]>

arrow.get('20160413')
# <Arrow [1970-08-22T08:06:53+00:00]>

pendulum.parse('20160413')
# <Pendulum [2016-04-13T00:00:00+00:00]>

arrow.get('2016-W07-5')
# <Arrow [2016-01-01T00:00:00+00:00]>

pendulum.parse('2016-W07-5')
# <Pendulum [2016-02-19T00:00:00+00:00]>

# 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 a few examples showing that Arrow cannot always be trusted to have a consistent behavior with the data you are passing to it.

Limitations

Even though the Pendulum class is a subclass of datetime there are some rare cases where it can’t replace the native class directly. Here is a list (non-exhaustive) of the reported cases with a possible solution, if any:

  • sqlite3 will use the the type() function to determine the type of the object by default. To work around it you can register a new adapter:

from pendulum import Pendulum
from sqlite3 import register_adapter

register_adapter(Pendulum, lambda val: val.isoformat(' '))
  • mysqlclient (former MySQLdb) and PyMySQL will use the the type() function to determine the type of the object by default. To work around it you can register a new adapter:

import MySQLdb.converters
import pymysql.converters

from pendulum import Pendulum

MySQLdb.converters.conversions[Pendulum] = MySQLdb.converters.DateTime2literal
pymysql.converters.conversions[Pendulum] = pymysql.converters.escape_datetime
  • django will use the isoformat() method to store datetimes in the database. However since pendulum is always timezone aware the offset information will always be returned by isoformat() raising an error, at least for MySQL databases. To work around it you can either create your own DateTimeField or use the previous workaround for MySQLdb:

from django.db.models import DateTimeField as BaseDateTimeField
from pendulum import Pendulum


class DateTimeField(BaseDateTimeField):

    def value_to_string(self, obj):
        val = self.value_from_object(obj)

        if isinstance(value, Pendulum):
            return value.to_datetime_string()

        return '' if val is None else val.isoformat()

Resources

Contributing

Contributions are welcome, especially with localization. Check the languages already supported, and if you want to add a new one, take the en file as a starting point and add tests accordingly.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pendulum-1.2.3.tar.gz (69.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pendulum-1.2.3-cp36-cp36m-manylinux1_x86_64.whl (124.4 kB view details)

Uploaded CPython 3.6m

pendulum-1.2.3-cp36-cp36m-manylinux1_i686.whl (124.3 kB view details)

Uploaded CPython 3.6m

pendulum-1.2.3-cp36-cp36m-macosx_10_11_x86_64.whl (110.4 kB view details)

Uploaded CPython 3.6mmacOS 10.11+ x86-64

pendulum-1.2.3-cp35-cp35m-manylinux1_x86_64.whl (124.4 kB view details)

Uploaded CPython 3.5m

pendulum-1.2.3-cp35-cp35m-manylinux1_i686.whl (124.3 kB view details)

Uploaded CPython 3.5m

pendulum-1.2.3-cp27-cp27m-manylinux1_x86_64.whl (124.2 kB view details)

Uploaded CPython 2.7m

pendulum-1.2.3-cp27-cp27m-manylinux1_i686.whl (124.0 kB view details)

Uploaded CPython 2.7m

File details

Details for the file pendulum-1.2.3.tar.gz.

File metadata

  • Download URL: pendulum-1.2.3.tar.gz
  • Upload date:
  • Size: 69.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for pendulum-1.2.3.tar.gz
Algorithm Hash digest
SHA256 e5d056d371cb65355993c9fd439624945b6c50d5227dcbf57dcfab0845639c66
MD5 2ea6798ef17fb1fb395e6a12ed56b5e2
BLAKE2b-256 cb8b9dc4aba247a4357f6dfb1a0d21c03cfaf01f3aacde7cb5c478e4e9f418c6

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 38f8fd2bd4f0b20e55fa828d09643c8a2b29d0dba7960cd6d0bf74bf2feb6b49
MD5 e6837a83ed804d2e0229111b87dd7fd8
BLAKE2b-256 dd6cc69a8b69d413339992ab709ebd2f506b0a77136e66dcbe0655e55354ddeb

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp36-cp36m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp36-cp36m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 ad4257c4504dae8f031a5a487ad9ddcb92df5faa70a53c9d476b973ada6a572c
MD5 c70d9eedcd4206f7df2f6e035b708039
BLAKE2b-256 dbad238c6c116d791ef0ce6aa893a84135971e893e19bd3b7316471836ad8168

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp36-cp36m-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 d2a48c8d498399fe8476199a499347a2c1a73b0564f58eb71d11477f24df2aa5
MD5 688fd1eb6bd03135e7ff4af1c15b5949
BLAKE2b-256 ae6e0ff15363cfc2691059207f5a50f4050603f03533cfa278957a6da1e247ab

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 1c939fddd1b436917ffd7d11956d3bcc634cea573b55c29b11a2465902e866b4
MD5 17a5a495b818012f299dbad57df63f64
BLAKE2b-256 8f942f83e88cce617e1757474c197702339716c251bc2b2f6ce698d47c228c56

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp35-cp35m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp35-cp35m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 523115445ce17045fcea0d4a7da550f9065031a4ea8673bba9e38d1f16ecce02
MD5 a5ba61ad75f0b940c6e71ae1ed49ae55
BLAKE2b-256 54744c469a9ba4f7d62ef0daa6198a3576edfb87141040b5e0b2ca28ce34fb9d

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp27-cp27m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 43cf3c9285cdf59628a1cf9f6c550e511dc97f79decfcb0238e9a8164dcd2b20
MD5 1c7bece18ed5284c6212ef7740a7c8b7
BLAKE2b-256 16438b34bdd08cc63c3f2cab6edc9860d6754cef743430a588822379fd71e59a

See more details on using hashes here.

File details

Details for the file pendulum-1.2.3-cp27-cp27m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for pendulum-1.2.3-cp27-cp27m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 4198d6614fc9ff5680cacd131d4d210a27c572fdca3d1599e8ce7e38fad1c97e
MD5 8f2e8cfe982a41f2a23021630003574e
BLAKE2b-256 3b243a7f0599912a1988c385bcb747d9055d28ddf5b8a7b52aea52cb664aee93

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page