def parse_time_expression(value): def simple_date(sign, dig, type, floor): if dig or sign: from mo_logs import Log Log.error("can not accept a multiplier on a datetime") if floor: return Date(type).floor(Duration(floor)) else: return Date(type) terms = re.match(r'(\d*[|\w]+)\s*([+-]\s*\d*[|\w]+)*', value).groups() sign, dig, type = re.match(r'([+-]?)\s*(\d*)([|\w]+)', terms[0]).groups() if "|" in type: type, floor = type.split("|") else: floor = None if type in MILLI_VALUES.keys(): value = Duration(dig + type) else: value = simple_date(sign, dig, type, floor) for term in terms[1:]: if not term: continue sign, dig, type = re.match(r'([+-])\s*(\d*)([|\w]+)', term).groups() if "|" in type: type, floor = type.split("|") else: floor = None op = {"+": "__add__", "-": "__sub__"}[sign] if type in MILLI_VALUES.keys(): if floor: from mo_logs import Log Log.error("floor (|) of duration not accepted") value = value.__getattribute__(op)(Duration(dig + type)) else: value = value.__getattribute__(op)(simple_date( sign, dig, type, floor)) return value
def parse_time_expression(value): def simple_date(sign, dig, type, floor): if dig or sign: from mo_logs import Log Log.error("can not accept a multiplier on a datetime") if floor: return Date(type).floor(Duration(floor)) else: return Date(type) terms = re.match(r'(\d*[|\w]+)\s*([+-]\s*\d*[|\w]+)*', value).groups() sign, dig, type = re.match(r'([+-]?)\s*(\d*)([|\w]+)', terms[0]).groups() if "|" in type: type, floor = type.split("|") else: floor = None if type in MILLI_VALUES.keys(): value = Duration(dig+type) else: value = simple_date(sign, dig, type, floor) for term in terms[1:]: if not term: continue sign, dig, type = re.match(r'([+-])\s*(\d*)([|\w]+)', term).groups() if "|" in type: type, floor = type.split("|") else: floor = None op = {"+": "__add__", "-": "__sub__"}[sign] if type in MILLI_VALUES.keys(): if floor: from mo_logs import Log Log.error("floor (|) of duration not accepted") value = value.__getattribute__(op)(Duration(dig+type)) else: value = value.__getattribute__(op)(simple_date(sign, dig, type, floor)) return value
def unicode2Date(value, format=None): """ CONVERT UNICODE STRING TO UNIX TIMESTAMP VALUE """ # http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior if value == None: return None if format != None: try: if format.endswith("%S.%f") and "." not in value: value += ".000" return _unix2Date(datetime2unix(datetime.strptime(value, format))) except Exception as e: from mo_logs import Log Log.error("Can not format {{value}} with {{format}}", value=value, format=format, cause=e) value = value.strip() if value.lower() == "now": return _unix2Date(datetime2unix(_utcnow())) elif value.lower() == "today": return _unix2Date(math.floor(datetime2unix(_utcnow()) / 86400) * 86400) elif value.lower() in ["eod", "tomorrow"]: return _unix2Date( math.floor(datetime2unix(_utcnow()) / 86400) * 86400 + 86400) if any(value.lower().find(n) >= 0 for n in ["now", "today", "eod", "tomorrow"] + list(MILLI_VALUES.keys())): return parse_time_expression(value) try: # 2.7 DOES NOT SUPPORT %z local_value = parse_date(value) #eg 2014-07-16 10:57 +0200 return _unix2Date( datetime2unix( (local_value - coalesce(local_value.utcoffset(), 0)).replace(tzinfo=None))) except Exception as e: e = Except.wrap(e) # FOR DEBUGGING pass formats = [ "%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S.%f" ] for f in formats: try: return _unix2Date(datetime2unix(datetime.strptime(value, f))) except Exception: pass deformats = [ "%Y-%m", "%Y%m%d", "%d%m%Y", "%d%m%y", "%d%b%Y", "%d%b%y", "%d%B%Y", "%d%B%y", "%B%d%Y", "%b%d%Y", "%B%d%", "%b%d%y", "%Y%m%d%H%M%S%f", "%Y%m%d%H%M%S", "%Y%m%dT%H%M%S", "%d%m%Y%H%M%S", "%d%m%y%H%M%S", "%d%b%Y%H%M%S", "%d%b%y%H%M%S", "%d%B%Y%H%M%S", "%d%B%y%H%M%S" ] value = deformat(value) for f in deformats: try: return unicode2Date(value, format=f) except Exception: pass else: from mo_logs import Log Log.error("Can not interpret {{value}} as a datetime", value=value)
def unicode2Date(value, format=None): """ CONVERT UNICODE STRING TO UNIX TIMESTAMP VALUE """ ## http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior if value == None: return None if format != None: try: if format.endswith("%S.%f") and "." not in value: value += ".000" return _unix2Date(datetime2unix(datetime.strptime(value, format))) except Exception as e: from mo_logs import Log Log.error("Can not format {{value}} with {{format}}", value=value, format=format, cause=e) value = value.strip() if value.lower() == "now": return _unix2Date(datetime2unix(_utcnow())) elif value.lower() == "today": return _unix2Date(math.floor(datetime2unix(_utcnow()) / 86400) * 86400) elif value.lower() in ["eod", "tomorrow"]: return _unix2Date(math.floor(datetime2unix(_utcnow()) / 86400) * 86400 + 86400) if any(value.lower().find(n) >= 0 for n in ["now", "today", "eod", "tomorrow"] + list(MILLI_VALUES.keys())): return parse_time_expression(value) try: # 2.7 DOES NOT SUPPORT %z local_value = parse_date(value) #eg 2014-07-16 10:57 +0200 return _unix2Date(datetime2unix((local_value - local_value.utcoffset()).replace(tzinfo=None))) except Exception: pass formats = [ "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S.%f" ] for f in formats: try: return _unix2Date(datetime2unix(datetime.strptime(value, f))) except Exception: pass deformats = [ "%Y-%m",# eg 2014-07-16 10:57 +0200 "%Y%m%d", "%d%m%Y", "%d%m%y", "%d%b%Y", "%d%b%y", "%d%B%Y", "%d%B%y", "%Y%m%d%H%M%S", "%Y%m%dT%H%M%S", "%d%m%Y%H%M%S", "%d%m%y%H%M%S", "%d%b%Y%H%M%S", "%d%b%y%H%M%S", "%d%B%Y%H%M%S", "%d%B%y%H%M%S" ] value = deformat(value) for f in deformats: try: return unicode2Date(value, format=f) except Exception: pass else: from mo_logs import Log Log.error("Can not interpret {{value}} as a datetime", value= value)