1*e1fe3e4aSElliott Hughes"""fontTools.misc.timeTools.py -- tools for working with OpenType timestamps. 2*e1fe3e4aSElliott Hughes""" 3*e1fe3e4aSElliott Hughes 4*e1fe3e4aSElliott Hughesimport os 5*e1fe3e4aSElliott Hughesimport time 6*e1fe3e4aSElliott Hughesfrom datetime import datetime, timezone 7*e1fe3e4aSElliott Hughesimport calendar 8*e1fe3e4aSElliott Hughes 9*e1fe3e4aSElliott Hughes 10*e1fe3e4aSElliott Hughesepoch_diff = calendar.timegm((1904, 1, 1, 0, 0, 0, 0, 0, 0)) 11*e1fe3e4aSElliott Hughes 12*e1fe3e4aSElliott HughesDAYNAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] 13*e1fe3e4aSElliott HughesMONTHNAMES = [ 14*e1fe3e4aSElliott Hughes None, 15*e1fe3e4aSElliott Hughes "Jan", 16*e1fe3e4aSElliott Hughes "Feb", 17*e1fe3e4aSElliott Hughes "Mar", 18*e1fe3e4aSElliott Hughes "Apr", 19*e1fe3e4aSElliott Hughes "May", 20*e1fe3e4aSElliott Hughes "Jun", 21*e1fe3e4aSElliott Hughes "Jul", 22*e1fe3e4aSElliott Hughes "Aug", 23*e1fe3e4aSElliott Hughes "Sep", 24*e1fe3e4aSElliott Hughes "Oct", 25*e1fe3e4aSElliott Hughes "Nov", 26*e1fe3e4aSElliott Hughes "Dec", 27*e1fe3e4aSElliott Hughes] 28*e1fe3e4aSElliott Hughes 29*e1fe3e4aSElliott Hughes 30*e1fe3e4aSElliott Hughesdef asctime(t=None): 31*e1fe3e4aSElliott Hughes """ 32*e1fe3e4aSElliott Hughes Convert a tuple or struct_time representing a time as returned by gmtime() 33*e1fe3e4aSElliott Hughes or localtime() to a 24-character string of the following form: 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes >>> asctime(time.gmtime(0)) 36*e1fe3e4aSElliott Hughes 'Thu Jan 1 00:00:00 1970' 37*e1fe3e4aSElliott Hughes 38*e1fe3e4aSElliott Hughes If t is not provided, the current time as returned by localtime() is used. 39*e1fe3e4aSElliott Hughes Locale information is not used by asctime(). 40*e1fe3e4aSElliott Hughes 41*e1fe3e4aSElliott Hughes This is meant to normalise the output of the built-in time.asctime() across 42*e1fe3e4aSElliott Hughes different platforms and Python versions. 43*e1fe3e4aSElliott Hughes In Python 3.x, the day of the month is right-justified, whereas on Windows 44*e1fe3e4aSElliott Hughes Python 2.7 it is padded with zeros. 45*e1fe3e4aSElliott Hughes 46*e1fe3e4aSElliott Hughes See https://github.com/fonttools/fonttools/issues/455 47*e1fe3e4aSElliott Hughes """ 48*e1fe3e4aSElliott Hughes if t is None: 49*e1fe3e4aSElliott Hughes t = time.localtime() 50*e1fe3e4aSElliott Hughes s = "%s %s %2s %s" % ( 51*e1fe3e4aSElliott Hughes DAYNAMES[t.tm_wday], 52*e1fe3e4aSElliott Hughes MONTHNAMES[t.tm_mon], 53*e1fe3e4aSElliott Hughes t.tm_mday, 54*e1fe3e4aSElliott Hughes time.strftime("%H:%M:%S %Y", t), 55*e1fe3e4aSElliott Hughes ) 56*e1fe3e4aSElliott Hughes return s 57*e1fe3e4aSElliott Hughes 58*e1fe3e4aSElliott Hughes 59*e1fe3e4aSElliott Hughesdef timestampToString(value): 60*e1fe3e4aSElliott Hughes return asctime(time.gmtime(max(0, value + epoch_diff))) 61*e1fe3e4aSElliott Hughes 62*e1fe3e4aSElliott Hughes 63*e1fe3e4aSElliott Hughesdef timestampFromString(value): 64*e1fe3e4aSElliott Hughes wkday, mnth = value[:7].split() 65*e1fe3e4aSElliott Hughes t = datetime.strptime(value[7:], " %d %H:%M:%S %Y") 66*e1fe3e4aSElliott Hughes t = t.replace(month=MONTHNAMES.index(mnth), tzinfo=timezone.utc) 67*e1fe3e4aSElliott Hughes wkday_idx = DAYNAMES.index(wkday) 68*e1fe3e4aSElliott Hughes assert t.weekday() == wkday_idx, '"' + value + '" has inconsistent weekday' 69*e1fe3e4aSElliott Hughes return int(t.timestamp()) - epoch_diff 70*e1fe3e4aSElliott Hughes 71*e1fe3e4aSElliott Hughes 72*e1fe3e4aSElliott Hughesdef timestampNow(): 73*e1fe3e4aSElliott Hughes # https://reproducible-builds.org/specs/source-date-epoch/ 74*e1fe3e4aSElliott Hughes source_date_epoch = os.environ.get("SOURCE_DATE_EPOCH") 75*e1fe3e4aSElliott Hughes if source_date_epoch is not None: 76*e1fe3e4aSElliott Hughes return int(source_date_epoch) - epoch_diff 77*e1fe3e4aSElliott Hughes return int(time.time() - epoch_diff) 78*e1fe3e4aSElliott Hughes 79*e1fe3e4aSElliott Hughes 80*e1fe3e4aSElliott Hughesdef timestampSinceEpoch(value): 81*e1fe3e4aSElliott Hughes return int(value - epoch_diff) 82*e1fe3e4aSElliott Hughes 83*e1fe3e4aSElliott Hughes 84*e1fe3e4aSElliott Hughesif __name__ == "__main__": 85*e1fe3e4aSElliott Hughes import sys 86*e1fe3e4aSElliott Hughes import doctest 87*e1fe3e4aSElliott Hughes 88*e1fe3e4aSElliott Hughes sys.exit(doctest.testmod().failed) 89