# Making matplotlib's date2num and num2date perfect inverses

### Question

I'm trying to write a pair of functions, `plottm` and `unixtm`, which convert back and forth between normal unix time (seconds since 1970-01-01) and Matplotlib's date representation (days since the last day of -1BC or something, a float).

If `plottm` and `unixtm` were proper inverses then this code would print the same date/time twice:

``````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)))
``````

Alas, it's off by an hour (which only happens for some timestamps, otherwise I'd insert an offset and be done with it).

Probably related: Problems with Localtime

UPDATE: Related question that isn't specific to Matplotlib: Convert a unixtime to a datetime object and back again (pair of time conversion functions that are inverses)

1
2
5/23/2017 11:56:10 AM

Based on @dreeves answer, a solution adapted to work with timezone aware datetimes:

``````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)
``````

output (tested for several timezones):

``````2010-03-31 01:46:40+00:00 --> 2010-03-31 01:46:40+00:00
``````
3
11/6/2012 11:47:05 PM