Ejemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        """
        acceptable arg inputs:
          1) epoch micros integer (or int like)
          2) a datetime
            NOTE!! a naive datetime is assumed to be in UTC, unless you tell this
            method otherwise by also passing in a tz paramter.  A timezoned datetime is 
            preserved with the timezone it has
          3) a string representation that the dateutil parser can deal with
          4) multiple args just as datetime would accept

        acceptable keyworded inputs:
          1) us = an int/long in epoch micros
          2) ms = an int/long in epoch millis
          3) s = an int/long in epoch seconds
          4) m = an int/long in epoch minutes
          5) tz = a timezone (either a pytz timezone object, a recognizeable pytz timezone string, or a dateutil tz object)
        """
        super(SaneTime,self).__init__()
        uss = set()
        tzs = set()
        naive_dt = None
        avoid_localize = False

        for k,v in kwargs.iteritems():
            if k in ('tz','timezone'):
                tzs.add(SaneTime.to_timezone(v))
            elif k in MICROS_TRANSLATION_HASH:
                uss.add(MICROS_TRANSLATION_HASH[k]*v)
            else:
                raise TimeConstructionError("Unexpected kwarg in SaneTime constructor! (%s = %s)" % (k,v))

        args = list(args)
        if len(args)>2 and len(args)<=8:
            args = [fucked_datetime(*args)]
        if len(args)==2:
            tzs.add(SaneTime.to_timezone(args.pop()))
        if len(args)==1:
#            import pdb; pdb.set_trace()
            arg = args.pop()
            if hasattr(arg,'__int__'):
                uss.add(int(arg))
                if hasattr(arg,'tz'): tzs.add(arg.tz)
            elif isinstance(arg, basestring):
                parts = arg.strip().split(' ')
                if len(parts)>1 and parts[-1].startswith('+'):
                    try:
                        tzs.add(SaneTime.to_timezone(parts[-1][1:]))
                        arg = ' '.join(parts[:-1])
                    except: pass
                utc = arg.endswith('Z') or arg.endswith('+00:00')  # to deal with strange gunicorn issue -- doesn't want to use UTC time in these cases
                arg = crap_parser.parse(arg)
                if arg.tzinfo:  # parsed timezones are a special breed of retard
                    if utc:  # put this in place to guard against wierd gunicorn issue -- gunicorn will attempt to force local timezone when there's an explicit UTC timezone associated! not sure where that's coming from.
                        tzs.add(pytz.utc)
                        arg = arg.replace(tzinfo=None)
                    else:
                        # can't rely on the dateutil parser for timezone stuff-- so we go back to UTC and force tz to be set in other ways
                        avoid_localize = True # but we'll still convert back to UTC and allow timezone decoration
                        arg = arg.astimezone(pytz.utc).replace(tzinfo=None)
            if type(arg) == fucked_datetime:
                naive_dt = arg
                if naive_dt.tzinfo:
                    tzs.add(SaneTime.to_timezone(str(naive_dt.tzinfo)))
                    naive_dt = naive_dt.replace(tzinfo=None)

        if len(tzs)>1:
            raise TimeConstructionError("constructor arguments seem to specify more than one different timezone!  I can't possibly resolve that!  (timezones implied = %s)"%(tzs))

        # now we have enough info to figure out the tz:
        self.tz = len(tzs) and tzs.pop() or pytz.utc

        # and now that we've figured out tz, we can fully deconstruct the dt
        if naive_dt:
            if avoid_localize:
                uss.add(SaneTime.utc_datetime_to_us(naive_dt))
            else:
                uss.add(SaneTime.utc_datetime_to_us(self.tz.localize(naive_dt).astimezone(pytz.utc)))

        # if we got nothing yet for micros, then make it now
        if len(uss)==0:
            uss.add(SaneTime.utc_datetime_to_us(fucked_datetime.utcnow()))

        if len(uss)>1:
            raise TimeConstructionError("constructor arguments seem to specify more than one different time!  I can't possibly resolve that!  (micro times implied = %s)"%(uss))

        self.us = uss.pop()
        
        if len(args)>0:
            raise TimeConstructionError("Unexpected constructor arguments")
Ejemplo n.º 2
0
    def __init__(self, *args, **kwargs):
        """
        acceptable unkeyworded inputs:
          1) an int/long in utc micros
          2) a datetime
            NOTE!! a naive datetime is assumed to be in UTC, unless you tell this
            method otherwise by also passing in a tz paramter.  A timezoned datetime is 
            preserved with the timezone it has
          3) a string representation that the crap parser can deal with
          4) a string representation of the form /d+us or /d+ms or /d+s
          4) multiple args just as datetime would accept

        acceptable keyworded inputs:
          1) us = an int/long in utc micros
          2) ms = an int/long in utc millis
          3) s = an int/long in utc seconds
          4) tz = a timezone (either a pytz timezone object, a recognizeable pytz timezone string, or a dateutil tz object)
        """
        super(sanetime,self).__init__()
        uss = []
        tzs = []
        naive_dt = None

        args = list(args)
        if len(args)>2 and len(args)<8:
            args = [fucked_datetime(*args)]
        if len(args)==1:
            arg = args.pop()
            if type(arg) in [long,int,float,sanetime]:
                uss.append(int(arg))
            elif isinstance(arg, basestring):
                arg = arg.strip()
                native_format_match = self.__class__.STR_NATIVE_FORMAT.match(arg)
                if native_format_match:
                    kwargs[native_format_match.group(2)] = native_format_match.group(1)
                else:
                    arg = crap_parser.parse(arg)
                    if arg.tzinfo:  # parsed timezones are a special breed of retard
                        arg = arg.astimezone(pytz.utc).replace(tzinfo=None)
                        tzs.append('UTC') # don't allow for a tz specificaion on top of a timezoned datetime str  -- that is opening a whole extra can of confusion -- so force the timezone here so that another tz specification will cause an error
            if type(arg) == fucked_datetime:
                naive_dt = arg
                if naive_dt.tzinfo:
                    tzs.append(naive_dt.tzinfo)
                    naive_dt = naive_dt.replace(tzinfo=None)

        if kwargs.get('us'):
            uss.append(int(kwargs.pop('us')))
        if kwargs.get('ms'):
            uss.append(int(kwargs.pop('ms'))*1000)
        if kwargs.get('s'):
            uss.append(int(kwargs.pop('s'))*1000**2)

        if kwargs.get('tz'):
            tzs.append(kwargs.pop('tz'))


        # now we have enough info to figure out the tz:
        self._set_tz(tzs and tzs[0] or 'UTC')

        # and now that we've figured out tz, we can fully deconstruct the dt
        if naive_dt:
            dt = self._tz.localize(naive_dt).astimezone(pytz.utc)
            uss.append(shit_calendar.timegm(dt.timetuple())*1000**2+dt.microsecond)

        # if we got nothing yet for micros, then make it now
        if len(uss)==0:
            dt = fucked_datetime.utcnow()
            uss.append(shit_calendar.timegm(dt.timetuple())*1000**2+dt.microsecond)

        self.us = uss[0]
        
        if len(tzs)>1 or len(uss)>1 or len(args)>0:
            raise SaneTimeError('Unexpected constructor arguments')