2009年4月5日日曜日

Python: 世界の標準時間を相互に変換する

このブログ記事をはてなブックマークに追加

インターネットにより世界はとても身近なものになった。それはとても素晴らしいことなのだが、ある地域の現地時間が日本で何時なのかがすぐに分からず("4.30.2009 18:00 EET"なんて書かれていても分からないよね?)、いちいちネットで調べる羽目になることが度々ある。それが非常に煩わしかったので、Pythonを使ってコマンドラインで時間の変換を行えるようにしてみた。

標準時間の略名についてはネットで適当に検索してきてそれを利用している。プログラムのファイル名は一応standard_time.pyとしているが長すぎると思うのならst.pyなど好きに変えて使って欲しい。

使い方は以下の通り。変換先の標準時間が省略された場合はデフォルトで日本標準時(JST)となる。日付の指定は「年/月/日」とし、時刻は「時:分:秒」とする。年と秒は省略できる。

standard_time.py 日付 時刻 変換元の標準時間略名 [変換先の標準時間略名=JST]

例えば、米国東部夏時間(EDT)4月30日の午後6時を日本標準時(JST)に変換する場合は、

standard_time.py 4/30 18:00 EDT

とすれば良い。出力結果は以下のようになる。

米国東部夏時間(EDT) 2009-04-30 18:00:00 日本標準時間(JST) 2009-05-01 07:00:00

また、米国東部夏時間(EDT)4月30日の午後6時を米国山岳部標準時間(MST)に変換する場合は、

standard_time.py 4/30 18:00 EDT MST

とする。出力結果は以下の通り。

米国東部夏時間(EDT) 2009-04-30 18:00:00 米国山岳部標準時間(MST) 2009-04-30 15:00:00

以下にソースコードを示す。簡単なコードなので理解は容易だと思う。任意のフォーマットからの変換などの機能を組み込んでみるのも面白いかもしれない。もっとも、本格的にこの手のことをするならpytzを利用すべきかなぁ。でも、夏時間の判定をするわけではないし、それに標準時間の略号との対応が面倒そうなんだよね。

standard_time.py

#!/usr/bin/env python # -*- coding: utf-8 -*- """世界の標準時間を相互に変換""" import sys, os, datetime TIMEZONE_TABLE = { "NZDT" : ["+13:00", u"ニュージーランド夏時間"], "IDLE": ["+12:00", u"国際日付変更線の東側"], "NZST": ["+12:00", u"ニュージーランド標準時間"], "NZT": ["+12:00", u"ニュージーランド時間"], "AESST": ["+11:00", u"オーストラリア東部標準夏時間"], "ACSST": ["+10:30", u"オーストラリア中部標準夏時間"], "CADT": ["+10:30", u"オーストラリア中部夏時間"], "SADT": ["+10:30", u"オーストラリア南部夏時間"], "AEST": ["+10:00", u"オーストラリア東部標準時間"], "EAST": ["+10:00", u"オーストラリア東部標準時間"], "GST": ["+10:00", u"グアム標準時間"], "LIGT": ["+10:00", u"オーストラリア、メルボルン"], "SAST": ["+09:30", u"オーストラリア南部標準時間"], "CAST": ["+09:30", u"オーストラリア中部標準時間"], "AWSST": ["+09:00", u"オーストラリア西部標準夏時間"], "JST": ["+09:00", u"日本標準時間"], "KST": ["+09:00", u"韓国標準時間"], "MHT": ["+09:00", u"マーシャル群島、クワジュリン時間"], "WDT": ["+09:00", u"オーストラリア西部夏時間"], "MT": ["+08:30", u"モルッカ諸島時間"], "AWST": ["+08:00", u"オーストラリア西部標準時間"], "CCT": ["+08:00", u"中国湾岸時間"], "WADT": ["+08:00", u"オーストラリア西部夏時間"], "WST": ["+08:00", u"オーストラリア西部標準時間"], "JT": ["+07:30", u"ジャワ島時間"], "ALMST": ["+07:00", u"アルマトイ夏時間"], "WAST": ["+07:00", u"オーストラリア西部標準時間"], "CXT": ["+07:00", u"クリスマス島時間"], "MMT": ["+06:30", u"ミャンマー時間"], "ALMT": ["+06:00", u"アルマトイ時間"], "MAWT": ["+06:00", u"南極大陸時間"], "IOT": ["+05:00", u"インドチャゴス時間"], "MVT": ["+05:00", u"モルディブ島時間"], "TFT": ["+05:00", u"ケルゲレン諸島時間"], "AFT": ["+04:30", u"アフガニスタン時間"], "EAST": ["+04:00", u"マダガスカル、アンタナナリボ"], "MUT": ["+04:00", u"モーリシャス島時間"], "RET": ["+04:00", u"レユニオン島時間"], "SCT": ["+04:00", u"マーヘ島時間"], "IRT": ["+03:30", u"イラン時間"], "IT": ["+03:30", u"イラン時間"], "EAT": ["+03:00", u"アンタナナリボ、コモロ時間"], "BT": ["+03:00", u"バクダッド時間"], "EETDST": ["+03:00", u"東ヨーロッパ夏時間"], "EEST": ["+03:00", u"東ヨーロッパ夏時間"], "HMT": ["+03:00", u"ギリシャ、ヘラ地中海時間"], "BDST": ["+02:00", u"英国二重夏時間"], "CEST": ["+02:00", u"中央ヨーロッパ夏時間"], "CETDST": ["+02:00", u"中央ヨーロッパ夏時間"], "EET": ["+02:00", u"東ヨーロッパ時間"], "FWT": ["+02:00", u"フランス冬時間"], "IST": ["+02:00", u"イスラエル標準時間"], "MEST": ["+02:00", u"中央ヨーロッパ夏時間"], "METDST": ["+02:00", u"中央ヨーロッパ夏時間"], "SST": ["+02:00", u"スウェーデン夏時間"], "BST": ["+01:00", u"英国夏時間"], "CET": ["+01:00", u"中央ヨーロッパ時間"], "DNT": ["+01:00", u"デンマーク標準時間"], "FST": ["+01:00", u"フランス夏時間"], "MET": ["+01:00", u"中央ヨーロッパ時間"], "MEWT": ["+01:00", u"中央ヨーロッパ冬時間"], "MEZ": ["+01:00", u"中央ヨーロッパ地域時間"], "NOR": ["+01:00", u"ノルウェー標準時間"], "SET": ["+01:00", u"セイシェル時間"], "SWT": ["+01:00", u"スウェーデン冬時間"], "WETDST": ["+01:00", u"西ヨーロッパ夏時間"], "WEST": ["+01:00", u"西ヨーロッパ夏時間"], "GMT": ["00:00", u"グリニッジ標準時間"], "UT": ["00:00", u"万国共通時間"], "UTC": ["00:00", u"協定世界時間"], "Z": ["00:00", u"協定世界時間"], "ZULU": ["00:00", u"協定世界時間"], "WET": ["00:00", u"西ヨーロッパ時間"], "WAT": ["-01:00", u"西アフリカ時間"], "FNST": ["-01:00", u"フェルナンド・デ・ノローニャ夏時間"], "FNT": ["-02:00", u"フェルナンド・デ・ノローニャ時間"], "BRST": ["-02:00", u"ブラジニア夏時間"], "NDT": ["-02:30", u"ニューファンドランド夏時間"], "ADT": ["-03:00", u"大西洋夏時間"], "BRT": ["-03:00", u"ブラジリア時間"], "NFT": ["-03:30", u"ニューファンドランド標準時間"], "NST": ["-03:30", u"ニューファンドランド標準時間"], "AST": ["-04:00", u"大西洋標準時間"], "ACST": ["-04:00", u"大西洋/ポルトアクリ夏時間"], "EDT": ["-04:00", u"米国東部夏時間"], "ACT": ["-05:00", u"大西洋/ポルトアクリ標準時間"], "CDT": ["-05:00", u"米国中部夏時間"], "EST": ["-05:00", u"米国東部標準時間"], "CST": ["-06:00", u"米国中部標準時間"], "MDT": ["-06:00", u"米国山岳部夏時間"], "MST": ["-07:00", u"米国山岳部標準時間"], "PDT": ["-07:00", u"米国太平洋夏時間"], "AKDT": ["-08:00", u"アラスカ夏時間"], "PST": ["-08:00", u"米国太平洋標準時間"], "YDT": ["-08:00", u"ユーコン夏時間"], "AKST": ["-09:00", u"アラスカ標準時間"], "HDT": ["-09:00", u"ハワイ/アラスカ夏時間"], "YST": ["-09:00", u"ユーコン標準時間"], "MART": ["-09:30", u"マルケサス諸島時間"], "AHST": ["-10:00", u"ハワイ/アラスカ標準時間"], "HST": ["-10:00", u"ハワイ標準時間"], "CAT": ["-10:00", u"アラスカ中央時間"], "NT": ["-11:00", u"ノーム時間"], "IDLW": ["-12:00", u"国際日付変更線の西側"]} def standard_time(DATE, TIME, fZone, tZone): if fZone not in TIMEZONE_TABLE.keys(): print >>sys.stderr, u"変換元の標準時間略名が認識できません:", fZone sys.exit() if tZone not in TIMEZONE_TABLE.keys(): print >>sys.stderr, u"変換先の標準時間略名が認識できません:", tZone sys.exit() h, m = map(int, TIMEZONE_TABLE[fZone][0].split(":")) m *= -1 if TIMEZONE_TABLE[fZone][0].strip()[0] == "-" else 1 fST = datetime.timedelta(hours=h, minutes=m) h, m = map(int, TIMEZONE_TABLE[tZone][0].split(":")) m *= -1 if TIMEZONE_TABLE[fZone][0].strip()[0] == "-" else 1 tST = datetime.timedelta(hours=h, minutes=m) try: d = DATE.split("/") if len(d) == 2: Y = datetime.date.today().year M, D = map(int, d) elif len(d) == 3: Y, M, D = map(int, d) else: raise t = TIME.split(":") if len(t) == 2: h, m = map(int, t) s = 0 elif len(t) == 3: h, m, s = map(int, t) else: raise except: print >>sys.stderr, u"日時のフォーマットが間違っています:", DATE, TIME sys.exit() try: print u"%s(%s)" % (TIMEZONE_TABLE[fZone][1], fZone) print datetime.datetime(Y, M, D, hour=h, minute=m, second=s) print print u"%s(%s)" % (TIMEZONE_TABLE[tZone][1], tZone) print datetime.datetime(Y, M, D, hour=h, minute=m, second=s) + (tST - fST) except: print >>sys.stderr, u"日時に誤りがあります: %s %s %s" % (DATE, TIME, sys.exc_info()[1]) sys.exit() def main(args): if len(args) < 4: print >>sys.stderr, u"Usage: %s 日付 時刻 変換元の標準時間略名 [変換先の標準時間略名=JST]" % os.path.basename(args[0]) print >>sys.stderr, u" 日付: [年/]月/日 (例: 2009/4/3, 11/19)" print >>sys.stderr, u" 時刻: 時:分[:秒] (例: 19:50:23, 9:20)" print >>sys.stderr print >>sys.stderr, u" 使用例: " print >>sys.stderr, u" 米国東部夏時間(EDT)4月30日の午後6時を日本標準時(JST)に変換する場合" print >>sys.stderr, u" %s 4/30 18:00 EDT" % os.path.basename(args[0]) print >>sys.stderr print >>sys.stderr, u" 米国東部夏時間(EDT)4月30日の午後6時を米国太平洋標準時間(PST)に変換する場合" print >>sys.stderr, u" %s 4/30 18:00 EDT PST" % os.path.basename(args[0]) print >>sys.stderr print >>sys.stderr, u" 日本標準時(JST)4月30日の午後6時を米国東部夏時間(EDT)に変換する場合" print >>sys.stderr, u" %s 4/30 18:00 JST EDT" % os.path.basename(args[0]) sys.exit() DATE = args[1].replace("-", "/").replace(".", "/") TIME = args[2] fZone = args[3].upper() if len(args) == 4: tZone = "JST" else: tZone = args[4].upper() standard_time(DATE, TIME, fZone, tZone) if __name__ == "__main__": main(sys.argv)

追記(2009/4/8):

TIMEZONE_TABLEおよび時差計算の修正。

0 コメント: