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 and 3.4+.

>>> 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)

>>> 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.datetime(2013, 3, 31, 2, 30, tz='Europe/Paris')
'2013-03-31T03:30:00+02:00' # 2:30 does not exist (Skipped time)

# Proper handling of dst transitions
>>> just_before = pendulum.datetime(2013, 3, 31, 1, 59, 59, 999999, tz='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 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 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.datetime(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 DateTime 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 type() function to determine the type of the object by default. To work around it you can register a new adapter:

from pendulum import DateTime
from sqlite3 import register_adapter

register_adapter(DateTime, lambda val: val.isoformat(' '))
  • mysqlclient (former MySQLdb) and PyMySQL will use 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 DateTime

MySQLdb.converters.conversions[DateTime] = MySQLdb.converters.DateTime2literal
pymysql.converters.conversions[DateTime] = 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 DateTime


class DateTimeField(BaseDateTimeField):

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

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

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

Resources

Contributing

Contributions are welcome, especially with localization.

Getting started

To work on the Pendulum codebase, you’ll want to clone the project locally and install the required depedendencies via poetry.

$ git clone git@github.com:sdispater/pendulum.git
$ poetry install

Localization

If you want to help with localization, there are two different cases: the locale already exists or not.

If the locale does not exist you will need to create it by using the clock utility:

./clock locale:dump <your-locale>

It will generate a directory in pendulum/locales named after your locale, with the following structure:

<your-locale>/
    - custom.py
    - locale.py

The locale.py file must not be modified. It contains the translations provided by the CLDR database.

The custom.py file is the one you want to modify. It contains the data needed by Pendulum that are not provided by the CLDR database. You can take the en data as a reference to see which data is needed.

You should also add tests for the created or modified locale.

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-2.0.1.tar.gz (74.4 kB view details)

Uploaded Source

Built Distributions

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

pendulum-2.0.1-cp36-cp36m-manylinux1_x86_64.whl (137.2 kB view details)

Uploaded CPython 3.6m

pendulum-2.0.1-cp36-cp36m-manylinux1_i686.whl (136.5 kB view details)

Uploaded CPython 3.6m

pendulum-2.0.1-cp36-cp36m-macosx_10_13_x86_64.whl (415.5 kB view details)

Uploaded CPython 3.6mmacOS 10.13+ x86-64

pendulum-2.0.1-cp35-cp35m-manylinux1_x86_64.whl (137.1 kB view details)

Uploaded CPython 3.5m

pendulum-2.0.1-cp35-cp35m-manylinux1_i686.whl (136.4 kB view details)

Uploaded CPython 3.5m

pendulum-2.0.1-cp34-cp34m-manylinux1_x86_64.whl (136.7 kB view details)

Uploaded CPython 3.4m

pendulum-2.0.1-cp34-cp34m-manylinux1_i686.whl (136.1 kB view details)

Uploaded CPython 3.4m

pendulum-2.0.1-cp27-cp27m-manylinux1_x86_64.whl (92.8 kB view details)

Uploaded CPython 2.7m

pendulum-2.0.1-cp27-cp27m-manylinux1_i686.whl (92.8 kB view details)

Uploaded CPython 2.7m

File details

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

File metadata

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

File hashes

Hashes for pendulum-2.0.1.tar.gz
Algorithm Hash digest
SHA256 319eb6507e129ef14517805f4e1dcfcd01f2a8eeac55a61ec8f5d115f145f53e
MD5 86412b5ada2d1ac14b6f52db43be13bd
BLAKE2b-256 6a60458ac3edab4bb614033219f265e3662f5c3635a8b4680fa826d912943ceb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 930507c3af387315aca21cd7b1ba8148e7a0875aaa70f28de2f0f4fff61c70c5
MD5 9750e9d6b0f188354878356b91050a31
BLAKE2b-256 2e4a6ee21cd283e5961e2401f5eaebfc86301966ccbee9885e191e90bcac8519

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp36-cp36m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 d85e4f62547f681f59aefbe50606f161d9318103b35515edccce48c50fc373ff
MD5 c9cb639e237afb6527bfd00c067e919e
BLAKE2b-256 69aff6e5d94fadd5aab2e696ffeb66f095f2ec356dda3bc1f2b8d1e5424360be

See more details on using hashes here.

File details

Details for the file pendulum-2.0.1-cp36-cp36m-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-2.0.1-cp36-cp36m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 69c305e436402caa49e782e5dfc766b5a0b17a74d40acdbd1cefcf589ab90c88
MD5 9ae4ac800a27bbf867e878217969299e
BLAKE2b-256 2ed76ff80fd281016da9caeca53560ff60b9119a4d0152c6232240e1903652eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 deb2f38ac2fac5759094bcf0e0344154d3b0d5b2fe2b8962a533cdc4e67f609d
MD5 be2b855c4d16afb3e7e503bd84245e4d
BLAKE2b-256 22d464d604c7e8188bfa5275e5682cc26963db17c84aa14df37aa5d2489aee4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp35-cp35m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 a2d2e50890400a258166a7cfdf1a01164aa16bd402fd8b404c7131c3d9cf7c55
MD5 01ae438915792f566a9d5b8b166219fa
BLAKE2b-256 95fc6d8922093705fd34d4d2301616c3c9e5a18e7532b2e1ef4ef8b08f0e1986

See more details on using hashes here.

File details

Details for the file pendulum-2.0.1-cp34-cp34m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-2.0.1-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 0671c69452adaa685b3c6923ac7fc10b0b86e0c05bdad3c80bfa962e1e730f5b
MD5 86400f8c825ce216fd0d2058f6f4b2fd
BLAKE2b-256 12b6fc2b3ed8d3b8fe2f9e1189af7ad6fb1578c4e70e84bc18752d2e6a025d85

See more details on using hashes here.

File details

Details for the file pendulum-2.0.1-cp34-cp34m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for pendulum-2.0.1-cp34-cp34m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 6dc3c640cee078245271d407ce4fe74217518a57d5bd404addc017083c35cf9c
MD5 a3fb1a810f14d16c763aea0aa5b4ac05
BLAKE2b-256 fd176970d07b77ab6e7729df937b90619d4b41a5885d55f217e8bd0d5a7443f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 999ad7c9975b5ecc03b4fc2bbd7853650f3a272320bf92b3526601d008826c53
MD5 2e5ba2fd039f52c60a469f605af00ccd
BLAKE2b-256 6df520ed519a3e94f03f69ccf405aa413bdb2067e9a488a53c039b708a4fe69e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.1-cp27-cp27m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 4ff30c1e78e2e2f9b9caa833e04106a45502fe4504c2da88fd56c3da983b339a
MD5 92d48ff85f259293b96caae9a71b576d
BLAKE2b-256 97362c717ce98be1969072214bbc2180ea5799091daa0f031e95c697983243cc

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