Создание date2num matplotlib и num2date совершенных инверсий

Я пытаюсь написать пару функций, 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: конвертируйте unixtime в объект datetime и обратно (пара функций преобразования времени, которые являются обратными)

3 Solutions collect form web for “Создание date2num matplotlib и num2date совершенных инверсий”

Основываясь на ответе @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 

Существуют функции matplotlib.dates.epoch2num () / num2epoch, которые выполняют именно это:

 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 

Благодаря ответу FJ на аналогичный вопрос , я считаю, что лучший способ справиться с этим может быть следующим:

 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()) 
  • Опустить линии соединения в графике matplotlib, например y = tan (x)
  • Множественные перекрывающиеся участки с независимым масштабированием в Matplotlib
  • Matplotlib B1-Motion (движение мыши с нажатой клавишей) эквивалентно?
  • Класс периодических осей в matplotlib?
  • Нелинейное масштабирование цветовой карты для повышения контрастности
  • Легенда показывает только одну метку при построении с пандами
  • Установка тета-тиков в полярных графиках matplotlib
  • настройка цветового диапазона в matplotlib patchcollection
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.