def cert_time_to_seconds(cert_time): """Return the time in seconds since the Epoch as a floating point number, given the cert_time string representing the "notBefore" or "notAfter" date from a certificate in "%b %e %H:%M:%S %Y %Z" strptime format (C locale). >>> timestamp = cert_time_to_seconds("Jan 5 09:34:43 2018 GMT") >>> timestamp 1515144883.0 >>> from datetime import datetime >>> print(datetime.utcfromtimestamp(timestamp)) 2018-01-05 09:34:43 "notBefore" or "notAfter" dates must use GMT (rfc 3280). Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec (see ASN1_TIME_print()) """ import re from calendar import timegm #NOTE: it brings hardcoded Unix epoch (1970) months = [ "Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec" ] # ASN1_TIME_print format: "%s %2d %02d:%02d:%02d %d%s" m = re.match("(?i)" # case-insensitive for compatibility with strptime() "(?P{months}) " "(?P(?: |\d)\d) " "(?P\d\d):" "(?P\d\d):" "(?P\d\d) " "(?P\d+) GMT".format(months="|".join(months)), cert_time) # NOTE: regex is used instead of time.strptime() to avoid # dependence on the current locale if not m: raise ValueError('time data %r does not match ' 'format %r' % (cert_time, "%b %e %H:%M:%S %Y %Z")) month, *rest, year = m.groups() #NOTE: avoid datetime constructor to support leap seconds # return a float for compatibility (fractional seconds are always zero) return float(timegm((int(year), months.index(month.title()) + 1) + tuple(map(int, rest)))) if __name__ =="__main__": import doctest; doctest.testmod()