<s> import datetime <EOL> import time <EOL> import re <EOL> from . normalizing import normalize <EOL> from . misc import plural_or_not , roundup <EOL> from . robottypes import is_number , is_string <EOL> _timer_re = re . compile ( '<STR_LIT>' ) <EOL> def _get_timetuple ( epoch_secs = None ) : <EOL> if epoch_secs is None : <EOL> epoch_secs = time . time ( ) <EOL> secs , millis = _float_secs_to_secs_and_millis ( epoch_secs ) <EOL> timetuple = time . localtime ( secs ) [ : <NUM_LIT:6> ] <EOL> return timetuple + ( millis , ) <EOL> def _float_secs_to_secs_and_millis ( secs ) : <EOL> isecs = int ( secs ) <EOL> millis = roundup ( ( secs - isecs ) * <NUM_LIT:1000> ) <EOL> return ( isecs , millis ) if millis < <NUM_LIT:1000> else ( isecs + <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> def timestr_to_secs ( timestr , round_to = <NUM_LIT:3> ) : <EOL> """<STR_LIT>""" <EOL> if is_string ( timestr ) or is_number ( timestr ) : <EOL> for converter in _number_to_secs , _timer_to_secs , _time_string_to_secs : <EOL> secs = converter ( timestr ) <EOL> if secs is not None : <EOL> return secs if round_to is None else roundup ( secs , round_to ) <EOL> raise ValueError ( "<STR_LIT>" % timestr ) <EOL> def _number_to_secs ( number ) : <EOL> try : <EOL> return float ( number ) <EOL> except ValueError : <EOL> return None <EOL> def _timer_to_secs ( number ) : <EOL> match = _timer_re . match ( number ) <EOL> if not match : <EOL> return None <EOL> prefix , hours , minutes , seconds , millis = match . groups ( ) <EOL> seconds = float ( minutes ) * <NUM_LIT> + float ( seconds ) <EOL> if hours : <EOL> seconds += float ( hours [ : - <NUM_LIT:1> ] ) * <NUM_LIT> * <NUM_LIT> <EOL> if millis : <EOL> seconds += float ( millis [ <NUM_LIT:1> : ] ) / <NUM_LIT:10> ** len ( millis [ <NUM_LIT:1> : ] ) <EOL> if prefix == '<STR_LIT:->' : <EOL> seconds *= - <NUM_LIT:1> <EOL> return seconds <EOL> def _time_string_to_secs ( timestr ) : <EOL> timestr = _normalize_timestr ( timestr ) <EOL> if not timestr : <EOL> return None <EOL> millis = secs = mins = hours = days = <NUM_LIT:0> <EOL> if timestr [ <NUM_LIT:0> ] == '<STR_LIT:->' : <EOL> sign = - <NUM_LIT:1> <EOL> timestr = timestr [ <NUM_LIT:1> : ] <EOL> else : <EOL> sign = <NUM_LIT:1> <EOL> temp = [ ] <EOL> for c in timestr : <EOL> try : <EOL> if c == '<STR_LIT:x>' : millis = float ( '<STR_LIT>' . join ( temp ) ) ; temp = [ ] <EOL> elif c == '<STR_LIT:s>' : secs = float ( '<STR_LIT>' . join ( temp ) ) ; temp = [ ] <EOL> elif c == '<STR_LIT:m>' : mins = float ( '<STR_LIT>' . join ( temp ) ) ; temp = [ ] <EOL> elif c == '<STR_LIT:h>' : hours = float ( '<STR_LIT>' . join ( temp ) ) ; temp = [ ] <EOL> elif c == '<STR_LIT:d>' : days = float ( '<STR_LIT>' . join ( temp ) ) ; temp = [ ] <EOL> else : temp . append ( c ) <EOL> except ValueError : <EOL> return None <EOL> if temp : <EOL> return None <EOL> return sign * ( millis / <NUM_LIT:1000> + secs + mins * <NUM_LIT> + hours * <NUM_LIT> * <NUM_LIT> + days * <NUM_LIT> * <NUM_LIT> * <NUM_LIT> ) <EOL> def _normalize_timestr ( timestr ) : <EOL> timestr = normalize ( timestr ) <EOL> for specifier , aliases in [ ( '<STR_LIT:x>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] ) , <EOL> ( '<STR_LIT:s>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) , <EOL> ( '<STR_LIT:m>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) , <EOL> ( '<STR_LIT:h>' , [ '<STR_LIT>' ] ) , <EOL> ( '<STR_LIT:d>' , [ '<STR_LIT>' ] ) ] : <EOL> plural_aliases = [ a + '<STR_LIT:s>' for a in aliases if not a . endswith ( '<STR_LIT:s>' ) ] <EOL> for alias in plural_aliases + aliases : <EOL> if alias in timestr : <EOL> timestr = timestr . replace ( alias , specifier ) <EOL> return timestr <EOL> def secs_to_timestr ( secs , compact = False ) : <EOL> """<STR_LIT>""" <EOL> return _SecsToTimestrHelper ( secs , compact ) . get_value ( ) <EOL> class _SecsToTimestrHelper : <EOL> def __init__ ( self , float_secs , compact ) : <EOL> self . _compact = compact <EOL> self . _ret = [ ] <EOL> self . _sign , millis , secs , mins , hours , days = self . _secs_to_components ( float_secs ) <EOL> self . _add_item ( days , '<STR_LIT:d>' , '<STR_LIT>' ) <EOL> self . _add_item ( hours , '<STR_LIT:h>' , '<STR_LIT>' ) <EOL> self . _add_item ( mins , '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . _add_item ( secs , '<STR_LIT:s>' , '<STR_LIT>' ) <EOL> self . _add_item ( millis , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def get_value ( self ) : <EOL> if len ( self . _ret ) > <NUM_LIT:0> : <EOL> return self . _sign + '<STR_LIT:U+0020>' . join ( self . _ret ) <EOL> return '<STR_LIT>' if self . _compact else '<STR_LIT>' <EOL> def _add_item ( self , value , compact_suffix , long_suffix ) : <EOL> if value == <NUM_LIT:0> : <EOL> return <EOL> if self . _compact : <EOL> suffix = compact_suffix <EOL> else : <EOL> suffix = '<STR_LIT>' % ( long_suffix , plural_or_not ( value ) ) <EOL> self . _ret . append ( '<STR_LIT>' % ( value , suffix ) ) <EOL> def _secs_to_components ( self , float_secs ) : <EOL> if float_secs < <NUM_LIT:0> : <EOL> sign = '<STR_LIT>' <EOL> float_secs = abs ( float_secs ) <EOL> else : <EOL> sign = '<STR_LIT>' <EOL> int_secs , millis = _float_secs_to_secs_and_millis ( float_secs ) <EOL> secs = int_secs % <NUM_LIT> <EOL> mins = int_secs // <NUM_LIT> % <NUM_LIT> <EOL> hours = int_secs // ( <NUM_LIT> * <NUM_LIT> ) % <NUM_LIT> <EOL> days = int_secs // ( <NUM_LIT> * <NUM_LIT> * <NUM_LIT> ) <EOL> return sign , millis , secs , mins , hours , days <EOL> def format_time ( timetuple_or_epochsecs , daysep = '<STR_LIT>' , daytimesep = '<STR_LIT:U+0020>' , timesep = '<STR_LIT::>' , <EOL> millissep = None , gmtsep = None ) : <EOL> """<STR_LIT>""" <EOL> if is_number ( timetuple_or_epochsecs ) : <EOL> timetuple = _get_timetuple ( timetuple_or_epochsecs ) <EOL> else : <EOL> timetuple = timetuple_or_epochsecs <EOL> daytimeparts = [ '<STR_LIT>' % t for t in timetuple [ : <NUM_LIT:6> ] ] <EOL> day = daysep . join ( daytimeparts [ : <NUM_LIT:3> ] ) <EOL> time_ = timesep . join ( daytimeparts [ <NUM_LIT:3> : <NUM_LIT:6> ] ) <EOL> millis = millissep and '<STR_LIT>' % ( millissep , timetuple [ <NUM_LIT:6> ] ) or '<STR_LIT>' <EOL> return day + daytimesep + time_ + millis + _diff_to_gmt ( gmtsep ) <EOL> def _diff_to_gmt ( sep ) : <EOL> if not sep : <EOL> return '<STR_LIT>' <EOL> if time . altzone == <NUM_LIT:0> : <EOL> sign = '<STR_LIT>' <EOL> elif time . altzone > <NUM_LIT:0> : <EOL> sign = '<STR_LIT:->' <EOL> else : <EOL> sign = '<STR_LIT:+>' <EOL> minutes = abs ( time . altzone ) / <NUM_LIT> <EOL> hours , minutes = divmod ( minutes , <NUM_LIT> ) <EOL> return '<STR_LIT>' % ( sep , sep , sign , hours , minutes ) <EOL> def get_time ( format = '<STR_LIT>' , time_ = None ) : <EOL> """<STR_LIT>""" <EOL> time_ = int ( time_ or time . time ( ) ) <EOL> format = format . lower ( ) <EOL> if '<STR_LIT>' in format : <EOL> return time_ <EOL> timetuple = time . localtime ( time_ ) <EOL> parts = [ ] <EOL> for i , match in enumerate ( '<STR_LIT>' . split ( ) ) : <EOL> if match in format : <EOL> parts . append ( '<STR_LIT>' % timetuple [ i ] ) <EOL> if not parts : <EOL> return format_time ( timetuple , daysep = '<STR_LIT:->' ) <EOL> elif len ( parts ) == <NUM_LIT:1> : <EOL> return parts [ <NUM_LIT:0> ] <EOL> else : <EOL> return parts <EOL> def parse_time ( timestr ) : <EOL> """<STR_LIT>""" <EOL> for method in [ _parse_time_epoch , <EOL> _parse_time_timestamp , <EOL> _parse_time_now_and_utc ] : <EOL> seconds = method ( timestr ) <EOL> if seconds is not None : <EOL> return int ( seconds ) <EOL> raise ValueError ( "<STR_LIT>" % timestr ) <EOL> def _parse_time_epoch ( timestr ) : <EOL> try : <EOL> ret = float ( timestr ) <EOL> except ValueError : <EOL> return None <EOL> if ret < <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" % timestr ) <EOL> return ret <EOL> def _parse_time_timestamp ( timestr ) : <EOL> try : <EOL> return timestamp_to_secs ( timestr , ( '<STR_LIT:U+0020>' , '<STR_LIT::>' , '<STR_LIT:->' , '<STR_LIT:.>' ) ) <EOL> except ValueError : <EOL> return None <EOL> def _parse_time_now_and_utc ( timestr ) : <EOL> timestr = timestr . replace ( '<STR_LIT:U+0020>' , '<STR_LIT>' ) . lower ( ) <EOL> base = _parse_time_now_and_utc_base ( timestr [ : <NUM_LIT:3> ] ) <EOL> if base is not None : <EOL> extra = _parse_time_now_and_utc_extra ( timestr [ <NUM_LIT:3> : ] ) <EOL> if extra is not None : <EOL> return base + extra <EOL> return None <EOL> def _parse_time_now_and_utc_base ( base ) : <EOL> now = time . time ( ) <EOL> if base == '<STR_LIT>' : <EOL> return now <EOL> if base == '<STR_LIT>' : <EOL> zone = time . altzone if time . localtime ( ) . tm_isdst else time . timezone <EOL> return now + zone <EOL> return None <EOL> def _parse_time_now_and_utc_extra ( extra ) : <EOL> if not extra : <EOL> return <NUM_LIT:0> <EOL> if extra [ <NUM_LIT:0> ] not in [ '<STR_LIT:+>' , '<STR_LIT:->' ] : <EOL> return None <EOL> return ( <NUM_LIT:1> if extra [ <NUM_LIT:0> ] == '<STR_LIT:+>' else - <NUM_LIT:1> ) * timestr_to_secs ( extra [ <NUM_LIT:1> : ] ) <EOL> def get_timestamp ( daysep = '<STR_LIT>' , daytimesep = '<STR_LIT:U+0020>' , timesep = '<STR_LIT::>' , millissep = '<STR_LIT:.>' ) : <EOL> return TIMESTAMP_CACHE . get_timestamp ( daysep , daytimesep , timesep , millissep ) <EOL> def timestamp_to_secs ( timestamp , seps = None ) : <EOL> try : <EOL> secs = _timestamp_to_millis ( timestamp , seps ) / <NUM_LIT> <EOL> except ( ValueError , OverflowError ) : <EOL> raise ValueError ( "<STR_LIT>" % timestamp ) <EOL> else : <EOL> return roundup ( secs , <NUM_LIT:3> ) <EOL> def secs_to_timestamp ( secs , seps = None , millis = False ) : <EOL> if not seps : <EOL> seps = ( '<STR_LIT>' , '<STR_LIT:U+0020>' , '<STR_LIT::>' , '<STR_LIT:.>' if millis else None ) <EOL> ttuple = time . localtime ( secs ) [ : <NUM_LIT:6> ] <EOL> if millis : <EOL> millis = ( secs - int ( secs ) ) * <NUM_LIT:1000> <EOL> ttuple = ttuple + ( roundup ( millis ) , ) <EOL> return format_time ( ttuple , * seps ) <EOL> def get_elapsed_time ( start_time , end_time ) : <EOL> """<STR_LIT>""" <EOL> if start_time == end_time or not ( start_time and end_time ) : <EOL> return <NUM_LIT:0> <EOL> if start_time [ : - <NUM_LIT:4> ] == end_time [ : - <NUM_LIT:4> ] : <EOL> return int ( end_time [ - <NUM_LIT:3> : ] ) - int ( start_time [ - <NUM_LIT:3> : ] ) <EOL> start_millis = _timestamp_to_millis ( start_time ) <EOL> end_millis = _timestamp_to_millis ( end_time ) <EOL> return int ( end_millis - start_millis ) <EOL> def elapsed_time_to_string ( elapsed , include_millis = True ) : <EOL> """<STR_LIT>""" <EOL> prefix = '<STR_LIT>' <EOL> if elapsed < <NUM_LIT:0> : <EOL> prefix = '<STR_LIT:->' <EOL> elapsed = abs ( elapsed ) <EOL> if include_millis : <EOL> return prefix + _elapsed_time_to_string ( elapsed ) <EOL> return prefix + _elapsed_time_to_string_without_millis ( elapsed ) <EOL> def _elapsed_time_to_string ( elapsed ) : <EOL> secs , millis = divmod ( roundup ( elapsed ) , <NUM_LIT:1000> ) <EOL> mins , secs = divmod ( secs , <NUM_LIT> ) <EOL> hours , mins = divmod ( mins , <NUM_LIT> ) <EOL> return '<STR_LIT>' % ( hours , mins , secs , millis ) <EOL> def _elapsed_time_to_string_without_millis ( elapsed ) : <EOL> secs = roundup ( elapsed , ndigits = - <NUM_LIT:3> ) // <NUM_LIT:1000> <EOL> mins , secs = divmod ( secs , <NUM_LIT> ) <EOL> hours , mins = divmod ( mins , <NUM_LIT> ) <EOL> return '<STR_LIT>' % ( hours , mins , secs ) <EOL> def _timestamp_to_millis ( timestamp , seps = None ) : <EOL> if seps : <EOL> timestamp = _normalize_timestamp ( timestamp , seps ) <EOL> Y , M , D , h , m , s , millis = _split_timestamp ( timestamp ) <EOL> secs = time . mktime ( datetime . datetime ( Y , M , D , h , m , s ) . timetuple ( ) ) <EOL> return roundup ( <NUM_LIT:1000> * secs + millis ) <EOL> def _normalize_timestamp ( ts , seps ) : <EOL> for sep in seps : <EOL> if sep in ts : <EOL> ts = ts . replace ( sep , '<STR_LIT>' ) <EOL> ts = ts . ljust ( <NUM_LIT> , '<STR_LIT:0>' ) <EOL> return '<STR_LIT>' % ( ts [ : <NUM_LIT:4> ] , ts [ <NUM_LIT:4> : <NUM_LIT:6> ] , ts [ <NUM_LIT:6> : <NUM_LIT:8> ] , ts [ <NUM_LIT:8> : <NUM_LIT:10> ] , <EOL> ts [ <NUM_LIT:10> : <NUM_LIT:12> ] , ts [ <NUM_LIT:12> : <NUM_LIT> ] , ts [ <NUM_LIT> : <NUM_LIT> ] ) <EOL> def _split_timestamp ( timestamp ) : <EOL> years = int ( timestamp [ : <NUM_LIT:4> ] ) <EOL> mons = int ( timestamp [ <NUM_LIT:4> : <NUM_LIT:6> ] ) <EOL> days = int ( timestamp [ <NUM_LIT:6> : <NUM_LIT:8> ] ) <EOL> hours = int ( timestamp [ <NUM_LIT:9> : <NUM_LIT:11> ] ) <EOL> mins = int ( timestamp [ <NUM_LIT:12> : <NUM_LIT> ] ) <EOL> secs = int ( timestamp [ <NUM_LIT:15> : <NUM_LIT> ] ) <EOL> millis = int ( timestamp [ <NUM_LIT> : <NUM_LIT> ] ) <EOL> return years , mons , days , hours , mins , secs , millis <EOL> class TimestampCache ( object ) : <EOL> def __init__ ( self ) : <EOL> self . _previous_secs = None <EOL> self . _previous_separators = None <EOL> self . _previous_timestamp = None <EOL> def get_timestamp ( self , daysep = '<STR_LIT>' , daytimesep = '<STR_LIT:U+0020>' , timesep = '<STR_LIT::>' , millissep = '<STR_LIT:.>' ) : <EOL> epoch = self . _get_epoch ( ) <EOL> secs , millis = _float_secs_to_secs_and_millis ( epoch ) <EOL> if self . _use_cache ( secs , daysep , daytimesep , timesep ) : <EOL> return self . _cached_timestamp ( millis , millissep ) <EOL> timestamp = format_time ( epoch , daysep , daytimesep , timesep , millissep ) <EOL> self . _cache_timestamp ( secs , timestamp , daysep , daytimesep , timesep , millissep ) <EOL> return timestamp <EOL> def _get_epoch ( self ) : <EOL> return time . time ( ) <EOL> def _use_cache ( self , secs , * separators ) : <EOL> return self . _previous_timestamp and self . _previous_secs == secs and self . _previous_separators == separators <EOL> def _cached_timestamp ( self , millis , millissep ) : <EOL> if millissep : <EOL> return self . _previous_timestamp + millissep + format ( millis , '<STR_LIT>' ) <EOL> return self . _previous_timestamp <EOL> def _cache_timestamp ( self , secs , timestamp , daysep , daytimesep , timesep , millissep ) : <EOL> self . _previous_secs = secs <EOL> self . _previous_separators = ( daysep , daytimesep , timesep ) <EOL> self . _previous_timestamp = timestamp [ : - <NUM_LIT:4> ] if millissep else timestamp <EOL> TIMESTAMP_CACHE = TimestampCache ( ) </s>
