def _quarter_to_myear(year, quarter, freq): if quarter is not None: mnum = _month_numbers[_freq_mod._get_rule_month(freq)] + 1 month = (mnum + (quarter - 1) * 3) % 12 + 1 if month > mnum: year -= 1 return year, month
def _to_quarterly(year, month, freq='Q-DEC'): fmonth = _freq_mod._month_numbers[_freq_mod._get_rule_month(freq)] + 1 print fmonth mdiff = (month - fmonth) % 12 if month >= fmonth: mdiff += 12 ordin = 1 + (year - 1) * 4 + (mdiff - 1) / 3 return Period(ordin, freq=freq)
def _quarter_to_myear(year, quarter, freq): if quarter is not None: if quarter <= 0 or quarter > 4: raise ValueError('Quarter must be 1 <= q <= 4') mnum = _month_numbers[_freq_mod._get_rule_month(freq)] + 1 month = (mnum + (quarter - 1) * 3) % 12 + 1 if month > mnum: year -= 1 return year, month
def parse_time_string(arg, freq=None): """ Try hard to parse datetime string, leveraging dateutil plus some extra goodies like quarter recognition. Parameters ---------- arg : basestring freq : str or DateOffset, default None Helps with interpreting time string if supplied Returns ------- datetime, datetime/dateutil.parser._result, str """ from pandas.core.format import print_config from pandas.tseries.offsets import DateOffset from pandas.tseries.frequencies import (_get_rule_month, _month_numbers, _get_freq_str) if not isinstance(arg, basestring): return arg arg = arg.upper() try: default = datetime(1,1,1).replace(hour=0, minute=0, second=0, microsecond=0) # special handling for possibilities eg, 2Q2005, 2Q05, 2005Q1, 05Q1 if len(arg) in [4, 6]: add_century = False if len(arg) == 4: add_century = True qpats = [(qpat1, 1), (qpat2, 0)] else: qpats = [(qpat1full, 1), (qpat2full, 0)] for pat, yfirst in qpats: qparse = pat.match(arg) if qparse is not None: if yfirst: yi, qi = 1, 2 else: yi, qi = 2, 1 q = int(qparse.group(yi)) y_str = qparse.group(qi) y = int(y_str) if add_century: y += 2000 if freq is not None: # hack attack, #1228 mnum = _month_numbers[_get_rule_month(freq)] + 1 month = (mnum + (q - 1) * 3) % 12 + 1 if month > mnum: y -= 1 else: month = (q - 1) * 3 + 1 ret = default.replace(year=y, month=month) return ret, ret, 'quarter' is_mo_str = freq is not None and freq == 'M' is_mo_off = getattr(freq, 'rule_code', None) == 'M' is_monthly = is_mo_str or is_mo_off if len(arg) == 6 and is_monthly: try: ret = _try_parse_monthly(arg) if ret is not None: return ret, ret, 'month' except Exception: pass dayfirst = print_config.date_dayfirst yearfirst = print_config.date_yearfirst parsed = _dtparser._parse(arg, dayfirst=dayfirst, yearfirst=yearfirst) if parsed is None: raise DateParseError("Could not parse %s" % arg) repl = {} reso = 'year' stopped = False for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: can_be_zero = ['hour', 'minute', 'second', 'microsecond'] value = getattr(parsed, attr) if value is not None and (value != 0 or attr in can_be_zero): repl[attr] = value if not stopped: reso = attr else: raise DateParseError("Missing attribute before %s" % attr) else: stopped = True ret = default.replace(**repl) return ret, parsed, reso # datetime, resolution except Exception, e: raise DateParseError(e)
def parse_time_string(arg, freq=None, dayfirst=None, yearfirst=None): """ Try hard to parse datetime string, leveraging dateutil plus some extra goodies like quarter recognition. Parameters ---------- arg : compat.string_types freq : str or DateOffset, default None Helps with interpreting time string if supplied dayfirst : bool, default None If None uses default from print_config yearfirst : bool, default None If None uses default from print_config Returns ------- datetime, datetime/dateutil.parser._result, str """ from pandas.core.config import get_option from pandas.tseries.offsets import DateOffset from pandas.tseries.frequencies import _get_rule_month, _month_numbers, _get_freq_str if not isinstance(arg, compat.string_types): return arg arg = arg.upper() default = datetime(1, 1, 1).replace(hour=0, minute=0, second=0, microsecond=0) # special handling for possibilities eg, 2Q2005, 2Q05, 2005Q1, 05Q1 if len(arg) in [4, 6]: m = ypat.match(arg) if m: ret = default.replace(year=int(m.group(1))) return ret, ret, "year" add_century = False if len(arg) == 4: add_century = True qpats = [(qpat1, 1), (qpat2, 0)] else: qpats = [(qpat1full, 1), (qpat2full, 0)] for pat, yfirst in qpats: qparse = pat.match(arg) if qparse is not None: if yfirst: yi, qi = 1, 2 else: yi, qi = 2, 1 q = int(qparse.group(yi)) y_str = qparse.group(qi) y = int(y_str) if add_century: y += 2000 if freq is not None: # hack attack, #1228 mnum = _month_numbers[_get_rule_month(freq)] + 1 month = (mnum + (q - 1) * 3) % 12 + 1 if month > mnum: y -= 1 else: month = (q - 1) * 3 + 1 ret = default.replace(year=y, month=month) return ret, ret, "quarter" is_mo_str = freq is not None and freq == "M" is_mo_off = getattr(freq, "rule_code", None) == "M" is_monthly = is_mo_str or is_mo_off if len(arg) == 6 and is_monthly: try: ret = _try_parse_monthly(arg) if ret is not None: return ret, ret, "month" except Exception: pass # montly f7u12 mresult = _attempt_monthly(arg) if mresult: return mresult if dayfirst is None: dayfirst = get_option("display.date_dayfirst") if yearfirst is None: yearfirst = get_option("display.date_yearfirst") try: parsed, reso = dateutil_parse(arg, default, dayfirst=dayfirst, yearfirst=yearfirst) except Exception as e: # TODO: allow raise of errors within instead raise DateParseError(e) if parsed is None: raise DateParseError("Could not parse %s" % arg) return parsed, parsed, reso # datetime, resolution
def parse_time_string(arg, freq=None): """ Try hard to parse datetime string, leveraging dateutil plus some extra goodies like quarter recognition. Parameters ---------- arg : basestring freq : str or DateOffset, default None Helps with interpreting time string if supplied Returns ------- datetime, datetime/dateutil.parser._result, str """ from pandas.core.format import print_config from pandas.tseries.offsets import DateOffset from pandas.tseries.frequencies import _get_rule_month, _month_numbers, _get_freq_str if not isinstance(arg, basestring): return arg arg = arg.upper() default = datetime(1, 1, 1).replace(hour=0, minute=0, second=0, microsecond=0) # special handling for possibilities eg, 2Q2005, 2Q05, 2005Q1, 05Q1 if len(arg) in [4, 6]: add_century = False if len(arg) == 4: add_century = True qpats = [(qpat1, 1), (qpat2, 0)] else: qpats = [(qpat1full, 1), (qpat2full, 0)] for pat, yfirst in qpats: qparse = pat.match(arg) if qparse is not None: if yfirst: yi, qi = 1, 2 else: yi, qi = 2, 1 q = int(qparse.group(yi)) y_str = qparse.group(qi) y = int(y_str) if add_century: y += 2000 if freq is not None: # hack attack, #1228 mnum = _month_numbers[_get_rule_month(freq)] + 1 month = (mnum + (q - 1) * 3) % 12 + 1 if month > mnum: y -= 1 else: month = (q - 1) * 3 + 1 ret = default.replace(year=y, month=month) return ret, ret, "quarter" is_mo_str = freq is not None and freq == "M" is_mo_off = getattr(freq, "rule_code", None) == "M" is_monthly = is_mo_str or is_mo_off if len(arg) == 6 and is_monthly: try: ret = _try_parse_monthly(arg) if ret is not None: return ret, ret, "month" except Exception: pass dayfirst = print_config.date_dayfirst yearfirst = print_config.date_yearfirst try: parsed = _dtparser._parse(arg, dayfirst=dayfirst, yearfirst=yearfirst) except Exception, e: raise DateParseError(e)
def test_get_rule_month(): result = frequencies._get_rule_month('W') assert(result == 'DEC') result = frequencies._get_rule_month(offsets.Week()) assert(result == 'DEC') result = frequencies._get_rule_month('D') assert(result == 'DEC') result = frequencies._get_rule_month(offsets.Day()) assert(result == 'DEC') result = frequencies._get_rule_month('Q') assert(result == 'DEC') result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=12)) print(result == 'DEC') result = frequencies._get_rule_month('Q-JAN') assert(result == 'JAN') result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=1)) assert(result == 'JAN') result = frequencies._get_rule_month('A-DEC') assert(result == 'DEC') result = frequencies._get_rule_month(offsets.YearEnd()) assert(result == 'DEC') result = frequencies._get_rule_month('A-MAY') assert(result == 'MAY') result = frequencies._get_rule_month(offsets.YearEnd(month=5)) assert(result == 'MAY')
def test_get_rule_month(): result = frequencies._get_rule_month("W") assert result == "DEC" result = frequencies._get_rule_month(offsets.Week()) assert result == "DEC" result = frequencies._get_rule_month("D") assert result == "DEC" result = frequencies._get_rule_month(offsets.Day()) assert result == "DEC" result = frequencies._get_rule_month("Q") assert result == "DEC" result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=12)) print(result == "DEC") result = frequencies._get_rule_month("Q-JAN") assert result == "JAN" result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=1)) assert result == "JAN" result = frequencies._get_rule_month("A-DEC") assert result == "DEC" result = frequencies._get_rule_month(offsets.YearEnd()) assert result == "DEC" result = frequencies._get_rule_month("A-MAY") assert result == "MAY" result = frequencies._get_rule_month(offsets.YearEnd(month=5)) assert result == "MAY"
def parse_time_string(arg, freq=None, dayfirst=None, yearfirst=None): """ Try hard to parse datetime string, leveraging dateutil plus some extra goodies like quarter recognition. Parameters ---------- arg : compat.string_types freq : str or DateOffset, default None Helps with interpreting time string if supplied dayfirst : bool, default None If None uses default from print_config yearfirst : bool, default None If None uses default from print_config Returns ------- datetime, datetime/dateutil.parser._result, str """ from pandas.core.config import get_option from pandas.tseries.offsets import DateOffset from pandas.tseries.frequencies import (_get_rule_month, _month_numbers, _get_freq_str) if not isinstance(arg, compat.string_types): return arg arg = arg.upper() default = datetime(1, 1, 1).replace(hour=0, minute=0, second=0, microsecond=0) # special handling for possibilities eg, 2Q2005, 2Q05, 2005Q1, 05Q1 if len(arg) in [4, 6]: m = ypat.match(arg) if m: ret = default.replace(year=int(m.group(1))) return ret, ret, 'year' add_century = False if len(arg) == 4: add_century = True qpats = [(qpat1, 1), (qpat2, 0)] else: qpats = [(qpat1full, 1), (qpat2full, 0)] for pat, yfirst in qpats: qparse = pat.match(arg) if qparse is not None: if yfirst: yi, qi = 1, 2 else: yi, qi = 2, 1 q = int(qparse.group(yi)) y_str = qparse.group(qi) y = int(y_str) if add_century: y += 2000 if freq is not None: # hack attack, #1228 mnum = _month_numbers[_get_rule_month(freq)] + 1 month = (mnum + (q - 1) * 3) % 12 + 1 if month > mnum: y -= 1 else: month = (q - 1) * 3 + 1 ret = default.replace(year=y, month=month) return ret, ret, 'quarter' is_mo_str = freq is not None and freq == 'M' is_mo_off = getattr(freq, 'rule_code', None) == 'M' is_monthly = is_mo_str or is_mo_off if len(arg) == 6 and is_monthly: try: ret = _try_parse_monthly(arg) if ret is not None: return ret, ret, 'month' except Exception: pass # montly f7u12 mresult = _attempt_monthly(arg) if mresult: return mresult if dayfirst is None: dayfirst = get_option("display.date_dayfirst") if yearfirst is None: yearfirst = get_option("display.date_yearfirst") try: parsed, reso = dateutil_parse(arg, default, dayfirst=dayfirst, yearfirst=yearfirst) except Exception as e: # TODO: allow raise of errors within instead raise DateParseError(e) if parsed is None: raise DateParseError("Could not parse %s" % arg) return parsed, parsed, reso # datetime, resolution
def test_get_rule_month(): result = frequencies._get_rule_month('W') assert (result == 'DEC') result = frequencies._get_rule_month(offsets.Week()) assert (result == 'DEC') result = frequencies._get_rule_month('D') assert (result == 'DEC') result = frequencies._get_rule_month(offsets.Day()) assert (result == 'DEC') result = frequencies._get_rule_month('Q') assert (result == 'DEC') result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=12)) print(result == 'DEC') result = frequencies._get_rule_month('Q-JAN') assert (result == 'JAN') result = frequencies._get_rule_month(offsets.QuarterEnd(startingMonth=1)) assert (result == 'JAN') result = frequencies._get_rule_month('A-DEC') assert (result == 'DEC') result = frequencies._get_rule_month(offsets.YearEnd()) assert (result == 'DEC') result = frequencies._get_rule_month('A-MAY') assert (result == 'MAY') result = frequencies._get_rule_month(offsets.YearEnd(month=5)) assert (result == 'MAY')
def __init__(self, value=None, freq=None, ordinal=None, year=None, month=1, quarter=None, day=1, hour=0, minute=0, second=0): """ Represents an period of time Parameters ---------- value : Period or basestring, default None The time period represented (e.g., '4Q2005') freq : str, default None e.g., 'B' for businessday, ('T', 5) or '5T' for 5 minutes year : int, default None month : int, default 1 quarter : int, default None day : int, default 1 hour : int, default 0 minute : int, default 0 second : int, default 0 """ # freq points to a tuple (base, mult); base is one of the defined # periods such as A, Q, etc. Every five minutes would be, e.g., # ('T', 5) but may be passed in as a string like '5T' self.freq = None # ordinal is the period offset from the gregorian proleptic epoch self.ordinal = None if ordinal is not None and value is not None: raise ValueError(("Only value or ordinal but not both should be " "given but not both")) elif ordinal is not None: if not com.is_integer(ordinal): raise ValueError("Ordinal must be an integer") if freq is None: raise ValueError('Must supply freq for ordinal value') self.ordinal = ordinal elif value is None: if freq is None: raise ValueError("If value is None, freq cannot be None") if year is None: raise ValueError("If value is None, year cannot be None") base, mult = _gfc(freq) if mult != 1: raise ValueError('Only mult == 1 supported') if quarter is not None: mnum = _month_numbers[_freq_mod._get_rule_month(freq)] + 1 month = (mnum + (quarter - 1) * 3) % 12 + 1 if month > mnum: year -= 1 self.ordinal = lib.period_ordinal(year, month, day, hour, minute, second, base) elif isinstance(value, Period): other = value if freq is None or _gfc(freq) == _gfc(other.freq): self.ordinal = other.ordinal freq = other.freq else: converted = other.asfreq(freq) self.ordinal = converted.ordinal elif isinstance(value, basestring) or com.is_integer(value): if com.is_integer(value): if value <= 0: raise ValueError('Value must be greater than 0') value = str(value) value = value.upper() dt, parsed, reso = parse_time_string(value, freq) if freq is None: if reso == 'year': freq = 'A' elif reso == 'quarter': freq = 'Q' elif reso == 'month': freq = 'M' elif reso == 'day': freq = 'D' elif reso == 'hour': freq = 'H' elif reso == 'minute': freq = 'T' elif reso == 'second': freq = 'S' else: raise ValueError("Could not infer frequency for period") elif isinstance(value, datetime): dt = value if freq is None: raise ValueError('Must supply freq for datetime value') else: msg = "Value must be Period, string, integer, or datetime" raise ValueError(msg) base, mult = _gfc(freq) if mult != 1: raise ValueError('Only mult == 1 supported') if self.ordinal is None: self.ordinal = lib.period_ordinal(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, base) self.freq = _freq_mod._get_freq_str(base)
def parse_time_string(arg, freq=None): """ Try hard to parse datetime string, leveraging dateutil plus some extra goodies like quarter recognition. Parameters ---------- arg : basestring freq : str or DateOffset, default None Helps with interpreting time string if supplied Returns ------- datetime, datetime/dateutil.parser._result, str """ from pandas.core.format import print_config from pandas.tseries.offsets import DateOffset from pandas.tseries.frequencies import (_get_rule_month, _month_numbers, _get_freq_str) if not isinstance(arg, basestring): return arg arg = arg.upper() try: default = datetime(1,1,1).replace(hour=0, minute=0, second=0, microsecond=0) # special handling for possibilities eg, 2Q2005, 2Q05, 2005Q1, 05Q1 if len(arg) in [4, 6]: add_century = False if len(arg) == 4: add_century = True qpats = [(qpat1, 1), (qpat2, 0)] else: qpats = [(qpat1full, 1), (qpat2full, 0)] for pat, yfirst in qpats: qparse = pat.match(arg) if qparse is not None: if yfirst: yi, qi = 1, 2 else: yi, qi = 2, 1 q = int(qparse.group(yi)) y_str = qparse.group(qi) y = int(y_str) if add_century: y += 2000 if freq is not None: # hack attack, #1228 mnum = _month_numbers[_get_rule_month(freq)] + 1 month = (mnum + (q - 1) * 3) % 12 + 1 if month > mnum: y -= 1 else: month = (q - 1) * 3 + 1 ret = default.replace(year=y, month=month) return ret, ret, 'quarter' is_mo_str = freq is not None and freq == 'M' is_mo_off = getattr(freq, 'rule_code', None) == 'M' is_monthly = is_mo_str or is_mo_off if len(arg) == 6 and is_monthly: try: ret = _try_parse_monthly(arg) if ret is not None: return ret, ret, 'month' except Exception: pass dayfirst = print_config.date_dayfirst yearfirst = print_config.date_yearfirst parsed = _dtparser._parse(arg, dayfirst=dayfirst, yearfirst=yearfirst) if parsed is None: raise DateParseError("Could not parse %s" % arg) repl = {} reso = 'year' stopped = False for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: can_be_zero = ['hour', 'minute', 'second', 'microsecond'] value = getattr(parsed, attr) if value is not None and value != 0: # or attr in can_be_zero): repl[attr] = value if not stopped: reso = attr else: stopped = True break ret = default.replace(**repl) return ret, parsed, reso # datetime, resolution except Exception, e: raise DateParseError(e)