# # wpylib.datetime0_idt # Created: 20141015 # Wirawan Purwanto # # Simple date/time stamp using 64-bit integer. # This module is an internal module; the exported name will # be put in wpylib.datetime module. # """ wplib.datetime0_idt module Simple date/time stamp using 64-bit integer. The primary motivation of creating this class is to store date/time information in the most compact way, while keeping the ease of human readability. The internal format is very simple: YYYYMMDDhhmmssfff where: - YYYY = year (0 < YYYY <= 9999) - MM = month (1 <= MM <= 12) - DD = day - hh = hour (0 <= hh < 24) - mm = minutes - ss = seconds - fff = milliseconds The time is always expressed in terms of UTC to eliminate ambiguity of time zone, daylight savings time, etc. CAVEAT: The resolution of the time is only on the order of millisecond. Linux OS, for example, allows resolution down to nanoseconds! This is a 17-decimal-digit integer, which fits in a 64-bit range (9.22e+18). """ from wpylib.params import struct class idatetime(object): """Simple 8-byte integer representation of a date/time stamp. """ def __init__(self, idt=None): if idt != None: self.idt = idt def validate(self): raise NotImplementedError def split_values(self): """Splits the compact datetime into components. Warning: the values are NOT validated. """ idt = self.idt s = str(idt) R = struct() #R.YYYY, R.MM, R.DD, R.hh, R.mm, R.ss, R.fff # names are too cryptic # Use same member names as in datetime (in sofar it is possible): R.year, R.month, R.day, R.hour, R.minute, R.second, R.millisecond = map(int, [ s[:-13], # year s[-13:-11], # month s[-11:-9], # day s[-9:-7], # hour s[-7:-5], # min s[-5:-3], # sec s[-3:] # millisec ]) R.microsecond = R.millisecond * 1000 return R def join_values(self, R=None): """Joins the values contained in data structure 'R' to create a composite integer date. This is the converse of function 'split_values'. """ if R is None: R = self.R if hasattr(R, 'microsecond'): millisecond = R.microsecond // 1000 elif hasattr(R, 'millisecond'): millisecond = R.millisecond return R.year * 10000000000000 \ + R.month * 100000000000 \ + R.day * 1000000000 \ + R.hour * 10000000 \ + R.minute * 100000 \ + R.second * 1000 \ + millisecond def to_datetime(self): """Converts the object value to standard python datetime object. """ from datetime import datetime R = self.split_values() dt = datetime(R.year, R.month, R.day, R.hour, R.minute, R.second, R.microsecond) ''' idt = self.idt s = str(idt) YYYY, MM, DD, hh, mm, ss, ms = map(int, [ s[:-13], # year s[-13:-11], # month s[-11:-9], # day s[-9:-7], # hour s[-7:-5], # min s[-5:-3], # sec s[-3:] # millisec ]) dt = datetime(YYYY, MM, DD, hh, mm, ss, fff*1000) ''' return dt def str_iso8601(self): """Outputs the object according to ISO-8601 combined date/time format. No time zone is shown.""" R = self.split_values() fmt = "%(year)04d-%(month)02d-%(day)02dT%(hour)02d:%(minute)02d:%(second)02d.%(millisecond)03d" return fmt % R