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.1.0.tar.gz (65.6 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.1.0-cp36-cp36m-manylinux1_x86_64.whl (110.0 kB view details)

Uploaded CPython 3.6m

pendulum-1.1.0-cp36-cp36m-manylinux1_i686.whl (110.6 kB view details)

Uploaded CPython 3.6m

pendulum-1.1.0-cp36-cp36m-macosx_10_11_x86_64.whl (102.2 kB view details)

Uploaded CPython 3.6mmacOS 10.11+ x86-64

pendulum-1.1.0-cp35-cp35m-manylinux1_x86_64.whl (109.9 kB view details)

Uploaded CPython 3.5m

pendulum-1.1.0-cp35-cp35m-manylinux1_i686.whl (110.6 kB view details)

Uploaded CPython 3.5m

pendulum-1.1.0-cp27-cp27m-manylinux1_x86_64.whl (109.8 kB view details)

Uploaded CPython 2.7m

pendulum-1.1.0-cp27-cp27m-manylinux1_i686.whl (110.4 kB view details)

Uploaded CPython 2.7m

File details

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

File metadata

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

File hashes

Hashes for pendulum-1.1.0.tar.gz
Algorithm Hash digest
SHA256 be9fe8380a48166a23122a5d29529eca3df3adb09dd85ea939db0dc651b9f187
MD5 a5848d81e5342dadef09888a0e32494e
BLAKE2b-256 fc211c7307f52215b34e63c43eae2a21b71bb2b4e5bf80baffd851dae849a572

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 06ac3ee1b2f09a55697540b5c0dbe446f895521dddfd3266dfa2bf4eb1eb1b67
MD5 ac63a3b9ba19a73e7171aff3d8243c2f
BLAKE2b-256 49543e4bdc3107763f9396e1f9bf60c511ff1e56017ee1d6b6a01efceec91702

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp36-cp36m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 ff38fe9e7b632c4818a5fa05e1246c9519029e3c623514716307e4012d3908f5
MD5 fb8e2186e2894f9d305d4d300170fa7e
BLAKE2b-256 b592e3fd999432a2842ab610fee22aebb5897b215ef9a32717f408087485ccb2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 0ea1ef22f05da98241b89d0a60dd68425c19233c34f1887fe87670d1747c422e
MD5 4634fa7a95d5050a9f56066e8ef8fbe5
BLAKE2b-256 1995bd587394c6248cde13e4ee37ff91c43e43003c13ae38b8dbee9fcd6df0ee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 6cd037d885f06c9055aa21f89d6e57ae22d07bf7c6c09aa00aa15c27a2a58a13
MD5 a79d9401a61e15c4540b46896910d29e
BLAKE2b-256 87be9edb6dd58f636c2828fe0fefaf21d1652063b0d57035bc2f4abb6719ef68

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp35-cp35m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 f4aadf4a93667af461fb91c630fbfe978c8a620e5ee4d1982615bcf307d22ba4
MD5 dadc1b44e557964579e9e11a944378d3
BLAKE2b-256 0c7ee925677f43147ad23d9b3b0d23b6b85a4f206c4c59ac13bf5a42f0a770d2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 023cbbcc429e4fd7ba03437917c9c25ae020f8c3def2caacbf5666f0fbb9a4fc
MD5 b231d46264681a28b436f65cda01d7a3
BLAKE2b-256 5e93bb3e22cc270927931c0ba5a04a0b952d5711786849f811b6f4a6dea39bca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-1.1.0-cp27-cp27m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 9acc8bd95021994cc2a8cbfe701ec839f0492dc356e7139f421f92137f541aef
MD5 4648cf5c27cad8cf7b46f7d9258b66ab
BLAKE2b-256 d6de451ab94d6c39b8dd925dcffacf11841eacd6f1557f97582eac52ef81b194

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