Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/useful.py: 46%

97 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> 

5# License: https://pyasn1.readthedocs.io/en/latest/license.html 

6# 

7import datetime 

8 

9from pyasn1 import error 

10from pyasn1.type import char 

11from pyasn1.type import tag 

12from pyasn1.type import univ 

13 

14__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime'] 

15 

16NoValue = univ.NoValue 

17noValue = univ.noValue 

18 

19 

20class ObjectDescriptor(char.GraphicString): 

21 __doc__ = char.GraphicString.__doc__ 

22 

23 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

24 tagSet = char.GraphicString.tagSet.tagImplicitly( 

25 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7) 

26 ) 

27 

28 # Optimization for faster codec lookup 

29 typeId = char.GraphicString.getTypeId() 

30 

31 

32class TimeMixIn(object): 

33 

34 _yearsDigits = 4 

35 _hasSubsecond = False 

36 _optionalMinutes = False 

37 _shortTZ = False 

38 

39 class FixedOffset(datetime.tzinfo): 

40 """Fixed offset in minutes east from UTC.""" 

41 

42 # defaulted arguments required 

43 # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html 

44 def __init__(self, offset=0, name='UTC'): 

45 self.__offset = datetime.timedelta(minutes=offset) 

46 self.__name = name 

47 

48 def utcoffset(self, dt): 

49 return self.__offset 

50 

51 def tzname(self, dt): 

52 return self.__name 

53 

54 def dst(self, dt): 

55 return datetime.timedelta(0) 

56 

57 UTC = FixedOffset() 

58 

59 @property 

60 def asDateTime(self): 

61 """Create :py:class:`datetime.datetime` object from a |ASN.1| object. 

62 

63 Returns 

64 ------- 

65 : 

66 new instance of :py:class:`datetime.datetime` object 

67 """ 

68 text = str(self) 

69 if text.endswith('Z'): 

70 tzinfo = TimeMixIn.UTC 

71 text = text[:-1] 

72 

73 elif '-' in text or '+' in text: 

74 if '+' in text: 

75 text, plusminus, tz = text.partition('+') 

76 else: 

77 text, plusminus, tz = text.partition('-') 

78 

79 if self._shortTZ and len(tz) == 2: 

80 tz += '00' 

81 

82 if len(tz) != 4: 

83 raise error.PyAsn1Error('malformed time zone offset %s' % tz) 

84 

85 try: 

86 minutes = int(tz[:2]) * 60 + int(tz[2:]) 

87 if plusminus == '-': 

88 minutes *= -1 

89 

90 except ValueError: 

91 raise error.PyAsn1Error('unknown time specification %s' % self) 

92 

93 tzinfo = TimeMixIn.FixedOffset(minutes, '?') 

94 

95 else: 

96 tzinfo = None 

97 

98 if '.' in text or ',' in text: 

99 if '.' in text: 

100 text, _, ms = text.partition('.') 

101 else: 

102 text, _, ms = text.partition(',') 

103 

104 try: 

105 ms = int(ms) * 1000 

106 

107 except ValueError: 

108 raise error.PyAsn1Error('bad sub-second time specification %s' % self) 

109 

110 else: 

111 ms = 0 

112 

113 if self._optionalMinutes and len(text) - self._yearsDigits == 6: 

114 text += '0000' 

115 elif len(text) - self._yearsDigits == 8: 

116 text += '00' 

117 

118 try: 

119 dt = datetime.datetime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') 

120 

121 except ValueError: 

122 raise error.PyAsn1Error('malformed datetime format %s' % self) 

123 

124 return dt.replace(microsecond=ms, tzinfo=tzinfo) 

125 

126 @classmethod 

127 def fromDateTime(cls, dt): 

128 """Create |ASN.1| object from a :py:class:`datetime.datetime` object. 

129 

130 Parameters 

131 ---------- 

132 dt: :py:class:`datetime.datetime` object 

133 The `datetime.datetime` object to initialize the |ASN.1| object 

134 from 

135 

136 Returns 

137 ------- 

138 : 

139 new instance of |ASN.1| value 

140 """ 

141 text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') 

142 if cls._hasSubsecond: 

143 text += '.%d' % (dt.microsecond // 1000) 

144 

145 if dt.utcoffset(): 

146 seconds = dt.utcoffset().seconds 

147 if seconds < 0: 

148 text += '-' 

149 else: 

150 text += '+' 

151 text += '%.2d%.2d' % (seconds // 3600, seconds % 3600) 

152 else: 

153 text += 'Z' 

154 

155 return cls(text) 

156 

157 

158class GeneralizedTime(char.VisibleString, TimeMixIn): 

159 __doc__ = char.VisibleString.__doc__ 

160 

161 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

162 tagSet = char.VisibleString.tagSet.tagImplicitly( 

163 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24) 

164 ) 

165 

166 # Optimization for faster codec lookup 

167 typeId = char.VideotexString.getTypeId() 

168 

169 _yearsDigits = 4 

170 _hasSubsecond = True 

171 _optionalMinutes = True 

172 _shortTZ = True 

173 

174 

175class UTCTime(char.VisibleString, TimeMixIn): 

176 __doc__ = char.VisibleString.__doc__ 

177 

178 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

179 tagSet = char.VisibleString.tagSet.tagImplicitly( 

180 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23) 

181 ) 

182 

183 # Optimization for faster codec lookup 

184 typeId = char.VideotexString.getTypeId() 

185 

186 _yearsDigits = 2 

187 _hasSubsecond = False 

188 _optionalMinutes = False 

189 _shortTZ = False