Source code for CIME.date

import re
from CIME.XML.standard_module_setup import *
logger = logging.getLogger(__name__)
###############################################################################
[docs]def get_file_date(filename): ############################################################################### """ Returns the date associated with the filename as a date object representing the correct date Formats supported: "%Y-%m-%d_%h.%M.%s "%Y-%m-%d_%05s" "%Y-%m-%d-%05s" "%Y-%m-%d" "%Y-%m" "%Y.%m" >>> get_file_date("./ne4np4_oQU240.cam.r.0001-01-06-00435.nc") date(1, 1, 6, 0, 7, 15) >>> get_file_date("./ne4np4_oQU240.cam.r.0010-1-06_00435.nc") date(10, 1, 6, 0, 7, 15) >>> get_file_date("./ne4np4_oQU240.cam.r.0010-10.nc") date(10, 10, 1, 0, 0, 0) >>> get_file_date("0064-3-8_10.20.30.nc") date(64, 3, 8, 10, 20, 30) >>> get_file_date("0140-3-5") date(140, 3, 5, 0, 0, 0) >>> get_file_date("0140-3") date(140, 3, 1, 0, 0, 0) >>> get_file_date("0140.3") date(140, 3, 1, 0, 0, 0) """ # # TODO: Add these to config_archive.xml, instead of here # Note these must be in order of most specific to least # so that lesser specificities aren't used to parse greater ones re_formats = [r"[0-9]*[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}_[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}", # [yy...]yyyy-mm-dd_hh.MM.ss r"[0-9]*[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}[\-_][0-9]{1,5}", # [yy...]yyyy-mm-dd_sssss r"[0-9]*[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}", # [yy...]yyyy-mm-dd r"[0-9]*[0-9]{4}[\-\.][0-9]{1,2}", # [yy...]yyyy-mm ] for re_str in re_formats: match = re.search(re_str, filename) if match is None: continue date_str = match.group() date_tuple = [int(unit) for unit in re.split(r"-|_|\.", date_str)] year = date_tuple[0] month = date_tuple[1] day = 1 second = 0 if len(date_tuple) > 2: day = date_tuple[2] if len(date_tuple) == 4: second = date_tuple[3] elif len(date_tuple) == 6: # Create a date object with arbitrary year, month, day, but the correct time of day # Then use _get_day_second to get the time of day in seconds second = date.hms_to_second(hour = date_tuple[3], minute = date_tuple[4], second = date_tuple[5]) return date(year, month, day, 0, 0, second) # Not a valid filename date format logger.debug("{} is a filename without a supported date!".format(filename)) return None
[docs]class date: """ Simple struct for holding dates and the time of day and performing comparisons Difference in Hour, Minute, or Second >>> date(4, 5, 6, 9) == date(4, 5, 6, 8) False >>> date(4, 5, 6, 9) != date(4, 5, 6, 8) True >>> date(4, 5, 6, 9) < date(4, 5, 6, 8) False >>> date(4, 5, 6, 9) <= date(4, 5, 6, 8) False >>> date(4, 5, 6, 9) >= date(4, 5, 6, 8) True >>> date(4, 5, 6, 9) > date(4, 5, 6, 8) True >>> date(4, 5, 6, 4) == date(4, 5, 6, 8) False >>> date(4, 5, 6, 4) != date(4, 5, 6, 8) True >>> date(4, 5, 6, 4) < date(4, 5, 6, 8) True >>> date(4, 5, 6, 4) <= date(4, 5, 6, 8) True >>> date(4, 5, 6, 4) >= date(4, 5, 6, 8) False >>> date(4, 5, 6, 4) > date(4, 5, 6, 8) False Difference in Day >>> date(4, 5, 8, 8) == date(4, 5, 6, 8) False >>> date(4, 5, 8, 8) != date(4, 5, 6, 8) True >>> date(4, 5, 8, 8) < date(4, 5, 6, 8) False >>> date(4, 5, 8, 8) <= date(4, 5, 6, 8) False >>> date(4, 5, 8, 8) >= date(4, 5, 6, 8) True >>> date(4, 5, 8, 8) > date(4, 5, 6, 8) True >>> date(4, 5, 5, 8) == date(4, 5, 6, 8) False >>> date(4, 5, 5, 8) != date(4, 5, 6, 8) True >>> date(4, 5, 5, 8) < date(4, 5, 6, 8) True >>> date(4, 5, 5, 8) <= date(4, 5, 6, 8) True >>> date(4, 5, 5, 8) >= date(4, 5, 6, 8) False >>> date(4, 5, 5, 8) > date(4, 5, 6, 8) False Difference in Month >>> date(4, 6, 6, 8) == date(4, 5, 6, 8) False >>> date(4, 6, 6, 8) != date(4, 5, 6, 8) True >>> date(4, 6, 6, 8) < date(4, 5, 6, 8) False >>> date(4, 6, 6, 8) <= date(4, 5, 6, 8) False >>> date(4, 6, 6, 8) >= date(4, 5, 6, 8) True >>> date(4, 6, 6, 8) > date(4, 5, 6, 8) True >>> date(4, 4, 6, 8) == date(4, 5, 6, 8) False >>> date(4, 4, 6, 8) != date(4, 5, 6, 8) True >>> date(4, 4, 6, 8) < date(4, 5, 6, 8) True >>> date(4, 4, 6, 8) <= date(4, 5, 6, 8) True >>> date(4, 4, 6, 8) >= date(4, 5, 6, 8) False >>> date(4, 4, 6, 8) > date(4, 5, 6, 8) False Difference in Year >>> date(5, 5, 6, 8) == date(4, 5, 6, 8) False >>> date(5, 5, 6, 8) != date(4, 5, 6, 8) True >>> date(5, 5, 6, 8) < date(4, 5, 6, 8) False >>> date(5, 5, 6, 8) <= date(4, 5, 6, 8) False >>> date(5, 5, 6, 8) >= date(4, 5, 6, 8) True >>> date(5, 5, 6, 8) > date(4, 5, 6, 8) True >>> date(3, 5, 6, 8) == date(4, 5, 6, 8) False >>> date(3, 5, 6, 8) != date(4, 5, 6, 8) True >>> date(3, 5, 6, 8) < date(4, 5, 6, 8) True >>> date(3, 5, 6, 8) <= date(4, 5, 6, 8) True >>> date(3, 5, 6, 8) >= date(4, 5, 6, 8) False >>> date(3, 5, 6, 8) > date(4, 5, 6, 8) False """
[docs] @staticmethod def hms_to_second(hour, minute, second): _SECONDS_PER_HOUR = 3600 _SECONDS_PER_MINUTE = 60 return (hour * _SECONDS_PER_HOUR + minute * _SECONDS_PER_MINUTE + second)
[docs] @staticmethod def second_to_hms(second): _SECONDS_PER_HOUR = 3600 _SECONDS_PER_MINUTE = 60 return { 'hour': second // _SECONDS_PER_HOUR, 'minute': (second % _SECONDS_PER_HOUR) // _SECONDS_PER_MINUTE, 'second': second % _SECONDS_PER_MINUTE }
def __init__(self, year=1, month=1, day=1, hour=0, minute=0, second=0): self._year = year self._month = month self._day = day self._second = self.hms_to_second(hour, minute, second) def __str__(self): """ >>> str(date(4, 5, 7, second=64)) 'date(4, 5, 7, 0, 1, 4)' """ fmt_str = "date({year:d}, {month:d}, {day:d}, {hour:d}, {minute:d}, {second:d})" return fmt_str.format(year = self.year(), month = self.month(), day = self.day(), hour = self.hour(), minute = self.minute(), second = self.second())
[docs] def year(self): return self._year
[docs] def month(self): return self._month
[docs] def day(self): return self._day
[docs] def hour(self): return self.second_to_hms(self._second)['hour']
[docs] def minute(self): return self.second_to_hms(self._second)['minute']
[docs] def second(self): return self.second_to_hms(self._second)['second']
[docs] def second_of_day(self): return self._second
def __repr__(self): return str(self) def __eq__(self, other): return ((self.year() == other.year()) and (self.month() == other.month()) and (self.day() == other.day()) and (self.second_of_day() == other.second_of_day())) def __ne__(self, other): return not (self == other) def __lt__(self, other): if self.year() < other.year(): return True elif self.year() > other.year(): return False # self.year == other.year if self.month() < other.month(): return True elif self.month() > other.month(): return False # self.month = other.month if self.day() < other.day(): return True elif self.day() > other.day(): return False # self.day = other.day if self.second_of_day() < other.second_of_day(): return True else: # the dates are equal return False def __le__(self, other): return ((self < other) or (self == other)) def __ge__(self, other): return not (self < other) def __gt__(self, other): return not (self <= other)