2015 01 22 23 26 [Python] utc time 與 local time 互轉.

python目前因為沒有提供tzinfo的實作.
導致沒有辦法直接使用timezone的資訊.
除非另外再安裝 pytz, 才有比較好的支援.

這時候就只能靠 datetime.fromtimestamp 和 datetime.utcfromtimestamp
除了時區, 還有日光節約時間的問題,
要拿到正確的timezone utc offset.
就必須要使用要轉換時間的timestamp.
例如:
from datetime import datetime
import calendar
d = datetime.utcnow()
ts = calendar.timegm(d.utctimetuple())
或者是用
d = datetime.strptime("1970-01-01 00:00:00","%Y-%m-%d %H:%M:%S")
ts = calendar.timegm(d.utctimetuple())
再來是 timestamp 是要轉成 local time,
datetime.fromtimestamp(ts)
這樣就可以得到localtime了~

如果是要從localtime轉成utc time的話.那就需要用
d = datetime.now()
ts = time.mktime(d.timetuple())
或者
d = datetime.strptime("1970-01-01 00:00:00","%Y-%m-%d %H:%M:%S")
ts = time.mktime(d.timetuple())
來生成timestamp.
再使用datetime.utcfromtimestamp(ts) 來轉出來utc time.


而可以這樣做的原理是因為,
fromtimestamp 事實上是會用 C 的 function localtime().
而 localtime() 是會參考 timezone 的資訊.
而 utcfromtimestamp 則是用到 gmtime().

舉例如下:
=====================================

#!/usr/bin/python

from datetime import datetime
import calendar
import time
import os

os.environ['TZ']='Asia/Taipei'
print "TZ=",os.getenv('TZ')
print utc_time = "2014-12-01 12:00:00.100000"
print "UTC   Time: ",utc_time
d = datetime.strptime(utc_time,"%Y-%m-%d %H:%M:%S.%f")
utc_ts = calendar.timegm(d.utctimetuple())
print "timestamp from utc: ",utc_ts
print "utc:",d
print "tw :",datetime.fromtimestamp(utc_ts).replace(microsecond=d.microsecond) print
local_time = "2014-12-01 20:00:00.100000"
print "Local Time: ",local_time
d = datetime.strptime(local_time,"%Y-%m-%d %H:%M:%S.%f")
tw_ts = time.mktime(d.timetuple())
print "timestamp from tw : ",tw_ts
print "tw :",d
print "utc:",datetime.utcfromtimestamp(tw_ts).replace(microsecond=d.microsecond)
print
print '========= Now ========='
d = datetime.now()
ts = time.mktime(d.timetuple())
print ' utc  time=',datetime.utcfromtimestamp(ts).replace(microsecond=d.microsecond)

d = datetime.utcnow()
ts = calendar.timegm(d.timetuple())
print 'local time=',datetime.fromtimestamp(ts).replace(microsecond=d.microsecond)

=====================================
執行如下結果:
$ ./test.py
TZ= Asia/Taipei

UTC   Time:  2014-12-01 12:00:00.100000
timestamp from utc:  1417435200
utc: 2014-12-01 12:00:00.100000
tw : 2014-12-01 20:00:00.100000

Local Time:  2014-12-01 20:00:00.100000
timestamp from tw :  1417435200.0
tw : 2014-12-01 20:00:00.100000
utc: 2014-12-01 12:00:00.100000

========= Now =========
 utc  time= 2015-01-23 04:45:58.605944
local time= 2015-01-23 12:45:58.605996
=====================================


Ref:

8.1. datetime — Basic date and time types — Python 2.7.9 documentation
15.3. time — Time access and conversions — Python 2.7.9 documentation

Update: 在範例中, 增加 microsecond 的部分.

PS: python 2.x datetime.strptime沒有支援 %z (utc offset).