123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #
- # This file is part of pyasn1 software.
- #
- # Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
- # License: http://snmplabs.com/pyasn1/license.html
- #
- import datetime
-
- from pyasn1 import error
- from pyasn1.compat import dateandtime
- from pyasn1.compat import string
- from pyasn1.type import char
- from pyasn1.type import tag
- from pyasn1.type import univ
-
- __all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime']
-
- NoValue = univ.NoValue
- noValue = univ.noValue
-
-
- class ObjectDescriptor(char.GraphicString):
- __doc__ = char.GraphicString.__doc__
-
- #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
- tagSet = char.GraphicString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7)
- )
-
- # Optimization for faster codec lookup
- typeId = char.GraphicString.getTypeId()
-
-
- class TimeMixIn(object):
-
- _yearsDigits = 4
- _hasSubsecond = False
- _optionalMinutes = False
- _shortTZ = False
-
- class FixedOffset(datetime.tzinfo):
- """Fixed offset in minutes east from UTC."""
-
- # defaulted arguments required
- # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html
- def __init__(self, offset=0, name='UTC'):
- self.__offset = datetime.timedelta(minutes=offset)
- self.__name = name
-
- def utcoffset(self, dt):
- return self.__offset
-
- def tzname(self, dt):
- return self.__name
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
- UTC = FixedOffset()
-
- @property
- def asDateTime(self):
- """Create :py:class:`datetime.datetime` object from a |ASN.1| object.
-
- Returns
- -------
- :
- new instance of :py:class:`datetime.datetime` object
- """
- text = str(self)
- if text.endswith('Z'):
- tzinfo = TimeMixIn.UTC
- text = text[:-1]
-
- elif '-' in text or '+' in text:
- if '+' in text:
- text, plusminus, tz = string.partition(text, '+')
- else:
- text, plusminus, tz = string.partition(text, '-')
-
- if self._shortTZ and len(tz) == 2:
- tz += '00'
-
- if len(tz) != 4:
- raise error.PyAsn1Error('malformed time zone offset %s' % tz)
-
- try:
- minutes = int(tz[:2]) * 60 + int(tz[2:])
- if plusminus == '-':
- minutes *= -1
-
- except ValueError:
- raise error.PyAsn1Error('unknown time specification %s' % self)
-
- tzinfo = TimeMixIn.FixedOffset(minutes, '?')
-
- else:
- tzinfo = None
-
- if '.' in text or ',' in text:
- if '.' in text:
- text, _, ms = string.partition(text, '.')
- else:
- text, _, ms = string.partition(text, ',')
-
- try:
- ms = int(ms) * 1000
-
- except ValueError:
- raise error.PyAsn1Error('bad sub-second time specification %s' % self)
-
- else:
- ms = 0
-
- if self._optionalMinutes and len(text) - self._yearsDigits == 6:
- text += '0000'
- elif len(text) - self._yearsDigits == 8:
- text += '00'
-
- try:
- dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
-
- except ValueError:
- raise error.PyAsn1Error('malformed datetime format %s' % self)
-
- return dt.replace(microsecond=ms, tzinfo=tzinfo)
-
- @classmethod
- def fromDateTime(cls, dt):
- """Create |ASN.1| object from a :py:class:`datetime.datetime` object.
-
- Parameters
- ----------
- dt: :py:class:`datetime.datetime` object
- The `datetime.datetime` object to initialize the |ASN.1| object
- from
-
- Returns
- -------
- :
- new instance of |ASN.1| value
- """
- text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
- if cls._hasSubsecond:
- text += '.%d' % (dt.microsecond // 1000)
-
- if dt.utcoffset():
- seconds = dt.utcoffset().seconds
- if seconds < 0:
- text += '-'
- else:
- text += '+'
- text += '%.2d%.2d' % (seconds // 3600, seconds % 3600)
- else:
- text += 'Z'
-
- return cls(text)
-
-
- class GeneralizedTime(char.VisibleString, TimeMixIn):
- __doc__ = char.VisibleString.__doc__
-
- #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
- tagSet = char.VisibleString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24)
- )
-
- # Optimization for faster codec lookup
- typeId = char.VideotexString.getTypeId()
-
- _yearsDigits = 4
- _hasSubsecond = True
- _optionalMinutes = True
- _shortTZ = True
-
-
- class UTCTime(char.VisibleString, TimeMixIn):
- __doc__ = char.VisibleString.__doc__
-
- #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
- tagSet = char.VisibleString.tagSet.tagImplicitly(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23)
- )
-
- # Optimization for faster codec lookup
- typeId = char.VideotexString.getTypeId()
-
- _yearsDigits = 2
- _hasSubsecond = False
- _optionalMinutes = False
- _shortTZ = False
|