時刻カラムがあるようなデータのプレ処理で、各レコードが米国サマータイム期間かどうか自動判定したいときとかあると思います。サマータイムかそうでないかで東京とニューヨークの時差が違うからね。
とりわけ、時刻カラムのタイムゾーンは日本時間なのですが、その時刻がニューヨークでサマータイムかどうかがほしいことがあると思います。以下の IS_DST 列を追加したいということです(サマータイム突入時には、現地では深夜2時を3時にジャンプさせますが、このジャンプ時刻は日本時間だと16時になります)。
時刻文字列を入れると、日本時間のその時刻にニューヨークではサマータイムかどうか返す関数があればよく、R だと例えば以下のようにかけます(参考: R の日付時刻オブジェクト - クッキーの日記)。
上の Python スクリプトでいま家では上手くいったんだけど、会社ではある1つの日付文字列から上の方法でサマータイムかどうかを上手く取得できなかった気がするんだよね(何かエラーが出た)。Pandas DataFrameで日時データのタイムゾーン変換 - pLog という記事によると、データフレーム型ではタイムスタンプをインデックスにしないと tz_convert ができないとあります。となると、ある1つの文字列に対して判定を行いたい場合、以下のようにすべきなのでしょうか…?
とりわけ、時刻カラムのタイムゾーンは日本時間なのですが、その時刻がニューヨークでサマータイムかどうかがほしいことがあると思います。以下の IS_DST 列を追加したいということです(サマータイム突入時には、現地では深夜2時を3時にジャンプさせますが、このジャンプ時刻は日本時間だと16時になります)。
DATETIME | IS_DST |
---|---|
2017/03/12 15:59:59 | 0 |
2017/03/12 16:00:00 | 1 |
is_dst <- function(datetime_string='2017/03/12 15:59:59') { time_lt <- strptime(datetime_string, format='%Y/%m/%d %H:%M:%S') time_ct <- as.POSIXct(time_lt, tz='Japan') return(as.POSIXlt(time_ct, tz="EST5EDT")$isdst == 1) } print(is_dst('2017/03/12 15:59:59')) # FALSE print(is_dst('2017/03/12 16:00:00')) # TRUE
ミソは、isdst のようなプロパティを取り出せるのは POSIXlt 型ですが、POSIXlt 型のままタイムゾーン間を行き来することはできないので、一旦 POSIXct 型を経由するところです(もっとスマートな方法があるかもしれないですがわからない)。
一方、Python では例えば以下のようにかけます(だいたい pandas をつかうので pandas.Timestamp 型をつかいます)。
# -*- coding: utf-8 -*- import pandas def is_dst(datetime_string='2017/03/12 15:59:59'): datetime = pandas.Timestamp(datetime_string) datetime = datetime.tz_localize('Asia/Tokyo') datetime = datetime.tz_convert('US/Eastern') return(datetime.dst().seconds > 0) if __name__ == "__main__": print(is_dst('2017/03/12 15:59:59')) # False print(is_dst('2017/03/12 16:00:00')) # True
時刻文字列をタイムスタンプに変換して、タイムゾーンを日本時間にして、アメリカ東部標準時に変換するだけです。dst() というメソッドは Standard Time との時差(つまり、サマータイムのときは1時間で、そうでなければ0時間)が取得できるようなので、0 より大きければサマータイムです。
上の Python スクリプトでいま家では上手くいったんだけど、会社ではある1つの日付文字列から上の方法でサマータイムかどうかを上手く取得できなかった気がするんだよね(何かエラーが出た)。Pandas DataFrameで日時データのタイムゾーン変換 - pLog という記事によると、データフレーム型ではタイムスタンプをインデックスにしないと tz_convert ができないとあります。となると、ある1つの文字列に対して判定を行いたい場合、以下のようにすべきなのでしょうか…?
def is_dst(datetime_string='2017/03/12 15:59:59'): df = pandas.DataFrame({'datetime': [datetime_string]}) df.index = pandas.DatetimeIndex(df.datetime, name='datetime') df.index = df.index.tz_localize('Asia/Tokyo') df.index = df.index.tz_convert('US/Eastern') return(df.index[0].dst().seconds > 0)
というかある1つの文字列に対して判定を行いたいだけなら pandas をつかわなくてもいいですね。
Python: How do you convert datetime/timestamp from one timezone to another timezone? - Stack Overflow
# -*- coding: utf-8 -*- import datetime import pytz def is_dst(datetime_string='2017/03/12 15:59:59'): dt0 = datetime.datetime.strptime(datetime_string, '%Y/%m/%d %H:%M:%S') tz0 = pytz.timezone('Asia/Tokyo') tz1 = pytz.timezone('US/Eastern') dt1 = tz0.localize(dt0).astimezone(tz1) return(dt1.dst().seconds > 0)