summaryrefslogtreecommitdiff
path: root/trove/common/timeutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'trove/common/timeutils.py')
-rw-r--r--trove/common/timeutils.py84
1 files changed, 84 insertions, 0 deletions
diff --git a/trove/common/timeutils.py b/trove/common/timeutils.py
new file mode 100644
index 00000000..44a0b9ff
--- /dev/null
+++ b/trove/common/timeutils.py
@@ -0,0 +1,84 @@
+# Copyright 2016 Tesora Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from datetime import datetime
+from datetime import timedelta
+from datetime import tzinfo
+
+
+class zulutime(tzinfo):
+ """A tzinfo class for zulu time"""
+
+ def utcoffset(self, dt):
+ return timedelta(0)
+
+ def tzname(self, dt):
+ return "Z"
+
+ def dst(self, dt):
+ return timedelta(0)
+
+
+def utcnow_aware():
+ """An aware utcnow() that uses zulutime for the tzinfo."""
+ return datetime.now(zulutime())
+
+
+def utcnow():
+ """A wrapper around datetime.datetime.utcnow(). We're doing this
+ because it is mock'ed in some places.
+ """
+ return datetime.utcnow()
+
+
+def isotime(tm=None, subsecond=False):
+ """Stringify a time and return it in an ISO 8601 format. Subsecond
+ information is only provided if the subsecond parameter is set
+ to True (default: False).
+
+ If a time (tm) is provided, it will be stringified. If tm is
+ not provided, the current UTC time is used instead.
+
+ The timezone for UTC time will be provided as 'Z' and not
+ [+-]00:00. Time zone differential for non UTC times will be
+ provided as the full six character string format provided by
+ datetime.datetime.isoformat() namely [+-]NN:NN.
+
+ If an invalid time is provided such that tm.utcoffset() causes
+ a ValueError, that exception will be propagated.
+ """
+
+ _dt = tm if tm else utcnow_aware()
+
+ if not subsecond:
+ _dt = _dt.replace(microsecond=0)
+
+ # might cause an exception if _dt has a bad utcoffset.
+ delta = _dt.utcoffset() if _dt.utcoffset() else timedelta(0)
+
+ ts = None
+
+ if delta == timedelta(0):
+ # either we are provided a naive time (tm) or no tm, or an
+ # aware UTC time. In any event, we want to use 'Z' for the
+ # timezone rather than the full 6 character offset.
+ _dt = _dt.replace(tzinfo=None)
+ ts = _dt.isoformat()
+ ts += 'Z'
+ else:
+ # an aware non-UTC time was provided
+ ts = _dt.isoformat()
+
+ return ts