* Upgraded utime_to_iso function to include more formatting.
This commit is contained in:
114
datetime.py
114
datetime.py
@@ -37,33 +37,101 @@ def shift_time(t, dt, localtime=True):
|
|||||||
else:
|
else:
|
||||||
return time.gmtime(t1)
|
return time.gmtime(t1)
|
||||||
|
|
||||||
def utime_to_iso(t=None, local=True):
|
|
||||||
|
class utime_to_iso_proc(object):
|
||||||
"""Converts UNIX time (seconds since Epoch) to ISO-formatted time string.
|
"""Converts UNIX time (seconds since Epoch) to ISO-formatted time string.
|
||||||
|
|
||||||
In order to ease time computation/conversion,
|
In order to ease time computation/conversion,
|
||||||
we will use numeric TZ shift (+/-HH:MM) instead of
|
we will use numeric TZ shift (+/-HH:MM) instead of
|
||||||
letter TZ code (EDT, EST, GMT, etc).
|
letter TZ code (EDT, EST, GMT, etc).
|
||||||
|
|
||||||
|
The full ISO-8601 format is like this:
|
||||||
|
|
||||||
|
YYYY-MM-DDThh:mm:ss.fffffffff+AA:BB
|
||||||
|
|
||||||
|
where
|
||||||
|
* YYYY-MM-DD = year, month, date
|
||||||
|
* hh:mm:ss.fff = hour, minute, second, fraction of the second
|
||||||
|
* AA:BB = time shift due to time zone
|
||||||
|
|
||||||
|
But some variants are valid:
|
||||||
|
* YYYY-MM-DD hh:mm (GNU ls timestyle 'long-iso')
|
||||||
|
* YYYY-MM-DD hh:mm.ss.fffffffff +AA:BB (GNU ls timestyle 'full-iso')
|
||||||
|
|
||||||
|
There are some built-in formats in this subroutine.
|
||||||
|
They can be tweaked further (adding new formats is OK; but changing
|
||||||
|
existing ones are not recommended).
|
||||||
|
|
||||||
|
The format string will undergo two passes:
|
||||||
|
* first pass, via strftime
|
||||||
|
* second pass, if '%' still exists in the string, expansion using 'opts'
|
||||||
|
computed variables.
|
||||||
|
|
||||||
|
Identifiers for second pass must be named, and must use '%%(NAME)s' kind of
|
||||||
|
format with double percent sign.
|
||||||
|
|
||||||
|
References:
|
||||||
|
* http://www.cl.cam.ac.uk/~mgk25/iso-time.html
|
||||||
|
* http://en.wikipedia.org/wiki/ISO_8601
|
||||||
|
* http://www.sqlite.org/lang_datefunc.html (subheading "Time Strings")
|
||||||
"""
|
"""
|
||||||
from time import time, localtime, gmtime, strftime, timezone
|
map_fmt_iso = {
|
||||||
if t == None:
|
0: "%Y-%m-%d %H:%M:%S %%(TZ)s", # original default of this routine
|
||||||
t = time()
|
'default': "%Y-%m-%d %H:%M:%S %%(TZ)s", # original default of this routine
|
||||||
if local:
|
# Global formats
|
||||||
tt = localtime(t)
|
'iso8601': "%Y-%m-%dT%H:%M:%S.%%(NANOSECS)s%%(ZTZ)s", # formal ISO-8601
|
||||||
dtz = -timezone + tt.tm_isdst * 3600
|
# GNU-specific formats
|
||||||
# hopefully dtz is divisible by 60
|
'gnu long-iso': "%Y-%m-%d %H:%M",
|
||||||
# It would be silly for a gov't to make its time
|
'gnu full-iso': "%Y-%m-%d %H:%M:%S.%%(NANOSECS)s %%(TZ)s",
|
||||||
# differ by seconds to GMT!
|
# My custom formats
|
||||||
dsec = abs(dtz) % 60
|
'idtstamp': "%Y-%m-%dT%H:%M:%S.%%(MILLISECS)s",
|
||||||
dmin = abs(dtz // 60) % 60
|
}
|
||||||
dhr = dtz // 3600
|
def __init__(self, fmt=0):
|
||||||
if dsec == 00:
|
from copy import copy
|
||||||
sdtz = " %+03d:%02d" % (dhr, dmin)
|
# Make a copy so we don't clobber the original class:
|
||||||
|
self.map_fmt_iso = copy(self.map_fmt_iso)
|
||||||
|
self.fmt = fmt
|
||||||
|
|
||||||
|
def __call__(self, t=None, local=True, fmt=None):
|
||||||
|
from time import time, localtime, gmtime, strftime, timezone
|
||||||
|
if fmt == None: fmt = self.fmt
|
||||||
|
if t == None:
|
||||||
|
t = time()
|
||||||
|
# The time, the nanosecond part:
|
||||||
|
t_ns = int((t - int(t)) * 1e+9)
|
||||||
|
opts = {
|
||||||
|
'NANOSECS': ("%09.0f" % t_ns),
|
||||||
|
'MICROSECS': ("%06.0f" % (t_ns // 1000)),
|
||||||
|
'MILLISECS': ("%03.0f" % (t_ns // 1000000)),
|
||||||
|
}
|
||||||
|
if local:
|
||||||
|
tt = localtime(t)
|
||||||
|
# dtz = Delta time due to Time Zone
|
||||||
|
dtz = -timezone + tt.tm_isdst * 3600
|
||||||
|
# hopefully dtz is divisible by 60
|
||||||
|
# It would be silly for a gov't to make its time
|
||||||
|
# differ by seconds to GMT!
|
||||||
|
dsec = abs(dtz) % 60
|
||||||
|
dmin = abs(dtz // 60) % 60
|
||||||
|
dhr = dtz // 3600
|
||||||
|
if dsec == 00:
|
||||||
|
opts['TZ'] = "%+03d:%02d" % (dhr, dmin)
|
||||||
|
else:
|
||||||
|
optz['TZ'] = "%+03d:%02d:%02d" % (dhr, dmin, dsec)
|
||||||
|
opts['ZTZ'] = opts['TZ']
|
||||||
else:
|
else:
|
||||||
sdtz = " %+03d:%02d:%02d" % (dhr, dmin, dsec)
|
tt = gmtime(t)
|
||||||
else:
|
opts['TZ'] = "+00:00"
|
||||||
tt = gmtime(t)
|
opts['ZTZ'] = "Z"
|
||||||
sdtz = " +00:00"
|
# Numeric timezone offset is created by hand
|
||||||
# Numeric timezone offset is created by hand
|
# because I don't want to use %Z, nor do I want to use
|
||||||
# because I don't want to use %Z, nor do I want to use
|
# "%z" (which did not work in python)
|
||||||
# "%z" (which did not work in python)
|
fmt = self.map_fmt_iso.get(fmt, fmt)
|
||||||
return strftime("%Y-%m-%d %H:%M:%S", tt) + sdtz
|
rslt1 = strftime(fmt, tt)
|
||||||
|
if "%" in rslt1:
|
||||||
|
rslt2 = rslt1 % opts
|
||||||
|
return rslt2
|
||||||
|
else:
|
||||||
|
return rslt1
|
||||||
|
|
||||||
|
utime_to_iso = utime_to_iso_proc()
|
||||||
|
|||||||
Reference in New Issue
Block a user