1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# $Id$
"""Unified RPKI date/time handling, based on the standard Python datetime module.
Module name chosen to sidestep a nightmare of import-related errors
that occur with the more obvious module names.
"""
import datetime as pydatetime
class datetime(pydatetime.datetime):
"""RPKI extensions to standard datetime.datetime class. All work
here is in UTC, so we use naive datetime objects.
"""
def totimestamp(self):
"""Convert to seconds from epoch (like time.time()). Conversion
method is a bit silly, but avoids time module timezone whackiness.
"""
return int(self.strftime("%s"))
@classmethod
def fromUTCTime(cls, x):
"""Convert from ASN.1 UTCTime."""
return cls.strptime(x, "%y%m%d%H%M%SZ")
def toUTCTime(self):
"""Convert to ASN.1 UTCTime."""
return self.strftime("%y%m%d%H%M%SZ")
@classmethod
def fromGeneralizedTime(cls, x):
"""Convert from ASN.1 GeneralizedTime."""
return cls.strptime(x, "%Y%m%d%H%M%SZ")
def toGeneralizedTime(self):
"""Convert to ASN.1 GeneralizedTime."""
return self.strftime("%Y%m%d%H%M%SZ")
@classmethod
def fromASN1tuple(cls, x):
"""Convert from ASN.1 tuple representation."""
assert isinstance(x, tuple) and len(x) == 2 and x[0] in ("utcTime", "generalTime")
if x[0] == "utcTime":
return cls.fromUTCTime(x)
else:
return cls.fromGeneralizedTime(x)
## @var PKIX_threshhold
# Threshold specified in RFC 3280 for switchover from UTCTime to GeneralizedTime.
PKIX_threshhold = pydatetime.datetime(2050, 1, 1)
def toASN1tuple(self):
"""Convert to ASN.1 tuple representation."""
if self < self.PKIX_threshhold:
return "utcTime", self.toUTCTime()
else:
return "generalTime", self.toGeneralizedTime()
@classmethod
def fromXMLtime(cls, x):
"""Convert from XML time representation."""
return cls.strptime(x, "%Y-%m-%dT%H:%M:%SZ")
def toXMLtime(self):
"""Convert to XML time representation."""
return self.strftime("%Y-%m-%dT%H:%M:%SZ")
@classmethod
def _cast(cls, x):
"""Convert a datetime.datetime object into this subclass.
This is whacky due to the weird constructors for datetime.
"""
return cls.combine(x.date(), x.time())
def __add__(self, other):
"""Force correct class for timedelta results."""
return self._cast(pydatetime.datetime.__add__(self, other))
def __sub__(self, other):
"""Force correct class for timedelta results."""
return self._cast(pydatetime.datetime.__sub__(self, other))
# Alias to simplify imports for callers
timedelta = pydatetime.timedelta
if __name__ == "__main__":
now = datetime.utcnow()
print now
print repr(now)
print now.strftime("%s")
print now.toUTCTime()
print now.toGeneralizedTime()
print now.toASN1tuple()
print now.toXMLtime()
print
then = now
then += timedelta(days = 30)
print then
print repr(then)
print then.strftime("%s")
print then.toUTCTime()
print then.toGeneralizedTime()
print then.toASN1tuple()
print then.toXMLtime()
|