added create_network(), delete_network(), create_subnet(), delete_subnet(), process_t...
[plcapi.git] / PLC / Timestamp.py
index 1b1f9ad..7087baf 100644 (file)
@@ -1,10 +1,5 @@
 #
 # 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
@@ -19,13 +14,14 @@ from PLC.Parameter import Parameter, Mixed
 
 # 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
@@ -34,10 +30,11 @@ class Timestamp:
                       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
@@ -49,17 +46,17 @@ class Timestamp:
     @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.
         """
@@ -108,7 +105,7 @@ class Timestamp:
         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,
@@ -128,7 +125,37 @@ class Timestamp:
             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