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:create <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.4.tar.gz (75.7 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.4-cp37-cp37m-manylinux1_x86_64.whl (139.6 kB view details)

Uploaded CPython 3.7m

pendulum-2.0.4-cp37-cp37m-macosx_10_14_x86_64.whl (404.8 kB view details)

Uploaded CPython 3.7mmacOS 10.14+ x86-64

pendulum-2.0.4-cp36-cp36m-manylinux1_x86_64.whl (139.5 kB view details)

Uploaded CPython 3.6m

pendulum-2.0.4-cp35-cp35m-manylinux1_x86_64.whl (139.4 kB view details)

Uploaded CPython 3.5m

pendulum-2.0.4-cp34-cp34m-manylinux1_x86_64.whl (139.0 kB view details)

Uploaded CPython 3.4m

pendulum-2.0.4-cp27-cp27m-manylinux1_x86_64.whl (93.9 kB view details)

Uploaded CPython 2.7m

File details

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

File metadata

  • Download URL: pendulum-2.0.4.tar.gz
  • Upload date:
  • Size: 75.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/0.12.5 CPython/3.7.1 Darwin/18.0.0

File hashes

Hashes for pendulum-2.0.4.tar.gz
Algorithm Hash digest
SHA256 cf535d36c063575d4752af36df928882b2e0e31541b4482c97d63752785f9fcb
MD5 058c10b8fcb290be9d2d7282e8b939d6
BLAKE2b-256 5b5771fc910edcd937b72aa0ef51c8f5734fbd8c011fa1480fce881433847ec8

See more details on using hashes here.

File details

Details for the file pendulum-2.0.4-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-2.0.4-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 5035a4e17504814a679f138374269cc7cc514aeac7ba6d9dc020abc224f25dbc
MD5 29ca5c08e4d82b532323141421c0df9d
BLAKE2b-256 607c236d09bebbeb550c9e5526a90ff5610a4432994dfd0bc029ff37f09c21c8

See more details on using hashes here.

File details

Details for the file pendulum-2.0.4-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for pendulum-2.0.4-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 bfc7b33ae193a204ec0bec12ad0d2d3300cd7e51d91d992da525ba3b28f0d265
MD5 6e437811c4f26ec646bd71928e60c35b
BLAKE2b-256 1c037b84db3d21741dc93ac0e89545010a143fc71437b24a7abdf9eff8a7e483

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.4-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 14e60d26d7400980123dbb6e3f2a90b70d7c18c63742ffe5bd6d6a643f8c6ef1
MD5 bea2e46292dc6dfb62b97ffed60b060f
BLAKE2b-256 69cc3eb8b945cad22589766bf4840976c115892df57ee7fa21864f1e50717444

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.4-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 8c0b3d655c1e9205d4dacf42fffc929cde3b19b5fb544a7f7561e6896eb8a000
MD5 3c8c113d82fe16f9f7f3d440cfb7bfe3
BLAKE2b-256 953791ea39046ea2523d72e0607a94e3ededd65f0d945ccb0e042f0aecd87dfc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.4-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 0f43d963b27e92b04047ce8352e4c277db99f20d0b513df7d0ceafe674a2f727
MD5 68c0dace0c0af673a5353a21fcdb64db
BLAKE2b-256 ce160e609ec9db540457ab90afa8bd6a3e8c4fd6d9a21968d11e450c55fa7448

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pendulum-2.0.4-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 cd70b75800439794e1ad8dbfa24838845e171918df81fa98b68d0d5a6f9b8bf2
MD5 c0443ca39c8ac37a86e9f992bf95ebaf
BLAKE2b-256 0197497eeb6cd333835792ce49021544446b767ed4a1be77fd06f72ce2cb93d4

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