1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python で、時差考慮で現在日時取得

Last updated at Posted at 2020-10-10

この記事について

この記事では、Python で現在日時を、時差考慮の上での取得方法について綴ったものです。
標準モジュール (datetime) のみの使用で、Python2 でも Python3 でも動く方法をメモしました。

datetimeモジュールの色々なメソッドやオブジェクトの詳しい説明は省いています。

きっかけ

Python で Web アプリを実装し、Heroku 上で動かそうとしていたときのこと。
ある機能の実装をしようとし、現在日時の取得の必要が。

単に現在時刻を取得しようとすると、Heroku サーバのシステム時刻が取得される。
Heroku サーバでは、+00:00 (UTC) でシステム時刻が動いている。

では、日本でアプリを動かしたとき、単に Heroku のシステム時刻が使われたらどうなるか。
アプリで機能を動かし、時刻取得をしたとき、日本時間 12:00 とします。
すると、Heroku のシステム時刻は 3:00。
日本時間は 12:00 だけど、アプリでは 3:00 として処理が進んでしまう。

んー、これじゃ良くない・・・。(カレンダー、リマインダーならなおさら。)
単に 9時間足してやればすぐ解決だが、せっかくだからサーバのタイムゾーン設定に依存せずに正確な日時が帰ってくるようにしたいな・・・。

手順

先に、とりあえず動くコード全体から示してしまいます。

import datetime

# UTC (協定世界時) の時刻を取得
time_now_utc = datetime.datetime.utcnow()
print(time_now_utc)
# 2020-10-10 14:51:22.910110

# UTC より、日本は 9時間進んでいる
time_dt_ja = datetime.timedelta(hours=9)
print(time_dt_ja)
# 9:00:00

# UTC に 9時間足してやれば、日本時間になる
time_now_ja = time_now_utc + time_dt_ja
print(time_now_ja)
# 2020-10-10 23:51:22.910110

1. まずは UTC (協定世界時) の取得

datetime.datetime.utcnow()で日時を取得してやると、稼働マシンのタイムゾーンが日本でもイギリスでもアメリカでも、同じ結果 (UTC) が得られます。
(datetime.datetime.now()だと、稼働マシンのタイムゾーン設定によって結果が変わってきてしまいます。)
まずはこれで稼働マシンのタイムゾーン設定の違いを埋めます。

time_now_utc = datetime.datetime.utcnow()

print(time_now_utc)
# 2020-10-10 14:51:22.910110

type(time_now_utc)
# <class 'datetime.datetime'>

ここではdatetimeオブジェクトが得られます。

2. 次に時差を適用する計算の準備

timedeltaオブジェクトの準備をします。
datetimeオブジェクトは時刻情報のオブジェクトで、timedelta時間情報のオブジェクトです。

time_dt_test = datetime.timedelta(days=1, seconds=1, microseconds=1, milliseconds=1, minutes=1, hours=1, weeks=1)

print(time_dt_test)
# 8 days, 1:01:01.001001

type(time_dt_test)
# <class 'datetime.timedelta'>

このような形で日 (週、日) や時間 (時間、分、秒) を指定してやると、日と時間情報に変換してくれます。

3. 最後に計算

datetimeオブジェクトとtimedeltaオブジェクトは、+ -で演算できます。
UTC に 9時間を足してやることで日本時間になるので、

time_now_ja = time_now_utc + time_dt_ja

print(time_now_ja)
# 2020-10-10 23:51:22.910110

あとは、適宜datetimeのメソッドを使うなりしておしまい。

print(time_now_ja.strftime("%Y年 %m月 %d日"))
# 2020年 10月 10日

strftime()についてですが、%Y, %d, %mだけでなく、色々な書式コードがあるようです。
詳しくは公式ドキュメントを参照
https://docs.python.org/ja/3/library/datetime.html#strftime-strptime-behavior

余談

公式ドキュメントによると、UTC の取得はdatetime.datetime.utcnow()よりも
datetime.datetime.now(datetime.timezone.utc)の方が推奨されているようです。

https://docs.python.org/ja/3/library/datetime.html

ただ、Python2 ではtimezoneオブジェクトが無いようです。

(でも、タイムゾーン関係はtimezoneオブジェクトを使っての実装の方が多分ずっとスマート。)

1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?