我正在尝试编写一对函数plottm
和unixtm
,它们在正常的unix时间(自1970-01-01以来的秒数)和Matplotlib的日期表示(天数)之间来回转换自-1BC的最后一天或其他东西,浮动)。
如果plottm
和unixtm
是正确的反转,则此代码会两次打印相同的日期/时间:
import time, datetime
import matplotlib.dates as dt
# Convert a unix time u to plot time p, and vice versa
def plottm(u): return dt.date2num(datetime.datetime.fromtimestamp(u))
def unixtm(p): return time.mktime(dt.num2date(p).timetuple())
u = 1270000000
print datetime.datetime.fromtimestamp(u), "-->", \
datetime.datetime.fromtimestamp(unixtm(plottm(u)))
唉,它已经过了一个小时(只有一些时间戳会发生,否则我会插入一个偏移并完成它)。
更新:相关问题并非特定于Matplotlib:Convert a unixtime to a datetime object and back again (pair of time conversion functions that are inverses)
答案 0 :(得分:3)
基于@dreeves的答案,一个适用于时区感知日期时间的解决方案:
import matplotlib.dates as dt
from calendar import timegm
from datetime import datetime
from pytz import utc
# Convert a unix time u to plot time p, and vice versa
def plottm(u):
return dt.date2num(datetime.fromtimestamp(u, utc))
def unixtm(p):
return timegm(dt.num2date(p, utc).utctimetuple())
u = 1270000000
print datetime.fromtimestamp(u, utc), "-->", \
datetime.fromtimestamp(unixtm(plottm(u)), utc)
输出(针对多个时区进行测试):
2010-03-31 01:46:40+00:00 --> 2010-03-31 01:46:40+00:00
答案 1 :(得分:2)
有matplotlib.dates.epoch2num()/num2epoch functions完全相同:
from datetime import datetime, timedelta
import matplotlib.dates as mpl_dt
matplotlib_epoch = datetime(1, 1, 1) # utc
posix_epoch = datetime(1970, 1, 1) # utc
DAY = 86400 # seconds
def plottm(u):
"""posix timestamp -> plot time"""
td = (datetime.utcfromtimestamp(u) - matplotlib_epoch)
return td.days + 1 + (1000000 * td.seconds + td.microseconds) / 1e6 / DAY
def unixtm(p):
"""plot time -> posix timestamp"""
td = timedelta(days=p-1)
return (matplotlib_epoch + td - posix_epoch).total_seconds()
def main():
f = datetime.utcfromtimestamp
u = 1270000000.1234567890
print(f(u))
print(mpl_dt.epoch2num(u))
print(plottm(u))
print(f(mpl_dt.num2epoch(mpl_dt.epoch2num(u))))
print(f(mpl_dt.num2epoch(plottm(u))))
print(f(unixtm(mpl_dt.epoch2num(u))))
print(f(unixtm(plottm(u))))
assert abs(mpl_dt.epoch2num(u) - plottm(u)) < 1e-5
p = 86401.234567890 / DAY
print(f(mpl_dt.num2epoch(p)))
print(f(unixtm(p)))
assert abs(mpl_dt.num2epoch(p) - unixtm(p)) < 1e-5
main()
2010-03-31 01:46:40.123457
733862.074076
733862.074076
2010-03-31 01:46:40.123453
2010-03-31 01:46:40.123453
2010-03-31 01:46:40.123453
2010-03-31 01:46:40.123453
0001-01-01 00:00:01.234566
0001-01-01 00:00:01.234566
答案 2 :(得分:1)
感谢F.J.对similar question的回答,我相信以下内容可能是解决此问题的最佳方式:
import datetime, calendar
import matplotlib.dates as dt
def plottm(u): return dt.date2num(datetime.datetime.utcfromtimestamp(u))
def unixtm(p): return calendar.timegm(dt.num2date(p).timetuple())