GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

sdispater

pendulum – Pythonのdatetimesで簡単にできた

投稿日:

Pythonのdatetimesで簡単にできた https://pendulum.eustace.io

振り子

Pythonのdatetimesは簡単にできました。

Python 2.7+3.4+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'

なぜ振り子ですか?

ネイティブのdatetimeインスタンスは基本的なケースでは十分ですが、より複雑なユースケースに直面すると、しばしば制限があり、それほど直感的ではありません。 Pendulumは、標準ライブラリに依存しながら、よりクリーンで使いやすいAPIを提供します。 だから、それはまだdatetimeが、より良いです。

Pendulumは、Pythonの他の日時ライブラリとは異なり、標準のdatetimeクラス(それを継承しています)の代わりに使用されるため、基本的には、コード内のPendulumインスタンスですべてのdatetimeインスタンスを置き換えることができます例えばsqlite3PyMySQLようなtype関数を使ってオブジェクトの型をPyMySQLします)。

また、純粋な日付表記の概念も取り除きます。それぞれのPendulumインスタンスはタイムゾーンを認識し、デフォルトでは使いやすさのためにUTCです。

ペンデュラムは、より直感的なメソッドやプロパティを提供することにより、標準的なtimedeltaクラスも向上させます。

なぜ矢じゃないの?

ArrowはPythonの最も普及している日時ライブラリですが、その動作やAPIは不安定で予期しないことがあります。 get()メソッドはかなり多くのものを受け取ることができ、いくつかのケースを静かに処理できない間に何かを返すように最善を尽くします:

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

これらの例は、矢印が渡されたデータと常に一貫した動作をすることを信頼できるとは限らないことを示しています。

制限事項

Pendulumクラスはdatetimeサブクラスですが、ネイティブクラスを直接置き換えることはできないまれなケースがいくつかあります。 報告されたケースのリスト(非限定的)

  • sqlite3は、 type()関数を使用してデフォルトでオブジェクトの型を決定します。 この問題を回避するには、新しいアダプターを登録することができます。
from pendulum import Pendulum
from sqlite3 import register_adapter

register_adapter(Pendulum, lambda val: val.isoformat(' '))
  • mysqlclient (旧MySQLdb )とPyMySQLtype()関数を使用してデフォルトでオブジェクトの型を判定します。 この問題を回避するには、新しいアダプターを登録することができます。
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
  • djangoisoformat()メソッドを使用してデータベースに日付時刻を格納します。 しかし、 pendulumは常にタイムゾーンを意識しているので、オフセット情報は少なくともMySQLデータベースの場合はエラーを起こすisoformat()によって返されます。 この問題を回避するには、独自のDateTimeField作成するか、以前の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()

リソース

貢献する

寄稿は歓迎されます。特にローカリゼーションが歓迎です。 すでにサポートされている言語を確認し、新しい言語を追加する場合は、 enファイルを開始点として使用し、それに応じてテストを追加します。







-sdispater
-, , , , ,

執筆者: