0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pendulum.parse時にTime情報のみを指定する時に気をつけること

Posted at

はじめに

Pythonでdatetime型を少しリッチに使おうと思ったら、pendulumが便利。

pendulumを用いて文字列からdatetime型を生成する時、 pendulum.parse を用いる。

この時、RFC3339やISO8601フォーマットである日時の文字列の他に、
2012-01-01 といった日付文字列や、 00:00 時間情報の文字列でもdatetime型を生成することができる。

>>> import pendulum
>>> pendulum.parse("2012-01-01")
DateTime(2012, 1, 1, 0, 0, 0, tzinfo=Timezone('UTC'))

>>> pendulum.parse("00:00")
DateTime(2024, 2, 6, 0, 0, 0, tzinfo=Timezone('UTC'))

問題

pendulum.parse("18:00", tz='Asia/Tokyo')

と書くと、「実行時点のAsia/Tokyoタイムゾーン日付の18:00のdatetime型」 を生成すると思っていたが、違うみたい。
実際には、 「実行時点のUTCタイムゾーン日付の18:00のdatetime型」 を返す。

例えば、実行時点が2024/02/02 03:00の場合、

# 期待する値
>>> pendulum.parse("18:00", tz='Asia/Tokyo')
DateTime(2024, 2, 2, 18, 0, 0, tzinfo=Timezone('Asia/Tokyo'))

# 実際の値
>>> pendulum.parse("18:00", tz='Asia/Tokyo')
DateTime(2024, 2, 1, 18, 0, 0, tzinfo=Timezone('Asia/Tokyo'))

期待していた値よりも1日ずれてしまう。

解決方法

では、「実行時点のAsia/Tokyoの日付で、時間情報のみを上書きしたDatetime型」 を生成したい場合どうしたらいいのか?

>>> import pendulum
>>> from datetime import datetime
>>> timezone = pendulum.timezone('Asia/Tokyo')
>>> today = pendulum.today(timezone)
>>> target_time = pendulum.parse("18:00", exact=True)
>>> datetime.combine(today, target_time)
datetime.datetime(2024, 2, 6, 18, 0)

exact=True にすることで、Time型が生成できるので、それを結合する。
(もっといい書き方がある気がする...?)

You can pass the exact keyword argument to parse() to get the exact type that the string represents:

おわりに

実行時点に依存する処理のバグは発見が難しい...

あと余談だが、 pendulum.parse の引数はチェックが甘いのでtypoにも気をつけたい。

# ↓が普通に実行できる
target_time = pendulum.parse("18:00", hogehoge="fugafuga")

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?