#
# Utilities to handle timestamps / durations from/to integers and strings
-#
-# $Id$
-# $URL$
-#
-
#
# datetime.{datetime,timedelta} are powerful tools, but these objects are not
# natively marshalled over xmlrpc
# a dummy class mostly used as a namespace
class Timestamp:
-
+
debug=False
# debug=True
# this is how we expose times to SQL
sql_format = "%Y-%m-%d %H:%M:%S"
sql_format_utc = "%Y-%m-%d %H:%M:%S UTC"
+
# this one (datetime.isoformat) would work too but that's less readable - we support this input though
iso_format = "%Y-%m-%dT%H:%M:%S"
# sometimes it's convenient to understand more formats
iso_format,
"%Y-%m-%d %H:%M",
"%Y-%m-%d %H:%M UTC",
+ "%Y-%m-%d %H:%M:%S.%f"
]
- # for timestamps we usually accept either an int, or an ISO string,
- # the datetime.datetime stuff can in general be used locally,
+ # for timestamps we usually accept either an int, or an ISO string,
+ # the datetime.datetime stuff can in general be used locally,
# but not sure it can be marshalled over xmlrpc though
@staticmethod
@staticmethod
def sql_validate (input, timezone=False, check_future = False):
"""
- Validates the specified GMT timestamp, returns a
+ Validates the specified GMT timestamp, returns a
standardized string suitable for SQL input.
Input may be a number (seconds since UNIX epoch back in 1970,
- or a string (in one of the supported input formats).
+ or a string (in one of the supported input formats).
- If timezone is True, the resulting string contains
+ If timezone is True, the resulting string contains
timezone information, which is hard-wired as 'UTC'
-
+
If check_future is True, raises an exception if timestamp is in
- the past.
+ the past.
Returns a GMT timestamp string suitable to feed SQL.
"""
Translates input timestamp as a unix timestamp.
Input may be a number (seconds since UNIX epoch, i.e., 1970-01-01
- 00:00:00 GMT), a string (in one of the supported input formats above).
+ 00:00:00 GMT), a string (in one of the supported input formats above).
"""
if Timestamp.debug: print 'cast_long, in:',input,
return result
else:
raise PLCInvalidArgument, "Timestamp %r - unsupported type %r"%(input,type(input))
+
+ def utcparse(input):
+ """ Translate a string into a time using dateutil.parser.parse but make
+ sure it's in UTC time and strip the timezone, so that it's compatible
+ with normal datetime.datetime objects.
+
+ For safety this can also handle inputs that are either timestamps, or
+ datetimes
+ """
+ # prepare the input for the checks below by
+ # casting strings ('1327098335') to ints
+ if isinstance(input, StringTypes):
+ try:
+ input = int(input)
+ except ValueError:
+ pass
+
+ if isinstance (input, datetime.datetime):
+ return input
+ elif isinstance (input, StringTypes):
+ t = dateutil.parser.parse(input)
+ if t.utcoffset() is not None:
+ t = t.utcoffset() + t.replace(tzinfo=None)
+ return t
+ elif isinstance (input, (int,float,long)):
+ return datetime.datetime.fromtimestamp(input)
+ else:
+ raise
+ def string(input):
+ return datetime.datetime.strftime(Timestamp.utcparse(input), Timestamp.sql_format)
# utility for displaying durations
# be consistent in avoiding the datetime stuff