xref: /aosp_15_r20/external/fonttools/Lib/fontTools/misc/timeTools.py (revision e1fe3e4ad2793916b15cccdc4a7da52a7e1dd0e9)
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