From 8cf8d50937aaef488359d19d6c2ab4ea937bde2d Mon Sep 17 00:00:00 2001
From: Alessandro Cerioni <acerioni@grandlyon.com>
Date: Sun, 10 Mar 2019 10:21:55 +0100
Subject: [PATCH] Bugfixes and improvements in utils/serializers.py. Added
 microseconds to the datetime strings formatted by the in doc-processor.

N.B.:
1. The previous version of the decode_datetime method in utils/serializers was never returning datetime objects.
2. Timezone information was lost.
---
 6-doc-processor.py   |  2 +-
 utils/serializers.py | 65 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/6-doc-processor.py b/6-doc-processor.py
index eae6c00..38d1b2d 100644
--- a/6-doc-processor.py
+++ b/6-doc-processor.py
@@ -48,7 +48,7 @@ def fix_field_types( in_docs, out_types ):
             elif out_types[lookup_key] == 'float':
                 out_flattened_properties[prop] = convert_to_float(in_flattened_properties[prop])
             elif out_types[lookup_key] in ['date', 'datetime']:
-                out_flattened_properties[prop] = convert_to_datetime(in_flattened_properties[prop]).strftime('%Y-%m-%dT%H:%M:%SZ')
+                out_flattened_properties[prop] = convert_to_datetime(in_flattened_properties[prop]).strftime('%Y-%m-%dT%H:%M:%S.%fZ')
             elif out_types[lookup_key] == 'bool':
                 out_flattened_properties[prop] = convert_to_boolean(in_flattened_properties[prop])
             else:
diff --git a/utils/serializers.py b/utils/serializers.py
index 04de436..3632e72 100644
--- a/utils/serializers.py
+++ b/utils/serializers.py
@@ -1,21 +1,76 @@
 import datetime
+import pytz
 
 # cf. https://stackoverflow.com/questions/30313243/messagepack-and-datetime
 def decode_datetime(obj):
     if '__datetime__' in obj.keys():
-        obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")
+        tmp = datetime.datetime.strptime(obj["as_str"], "%Y-%m-%dT%H:%M:%S.%fZ")
+        output = pytz.timezone('UTC').localize(tmp)
     elif '__date__' in obj.keys():
-        obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%d")
+        output = datetime.datetime.strptime(obj["as_str"], "%Y-%m-%d")
     else:
-        return obj
+        output = obj
+
+    return output
 
 # cf. https://stackoverflow.com/questions/30313243/messagepack-and-datetime
 def encode_datetime(obj):
     if isinstance(obj, datetime.datetime):
-        return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
+
+        if obj.tzinfo is None:
+            tmp1 = pytz.timezone("Europe/Paris").localize(obj)
+        else:
+            tmp1 = obj
+
+        tmp2 = tmp1.astimezone(pytz.UTC)
+
+        return {'__datetime__': True, 'as_str': tmp2.strftime("%Y-%m-%dT%H:%M:%S.%fZ")}
 
     if isinstance(obj, datetime.date):
-        return {'__date__': True, 'as_str': obj.strftime("%Y%m%d")}
+        return {'__date__': True, 'as_str': obj.strftime("%Y-%m-%d")}
     # if isinstance(obj, Decimal):
     #     return float(obj)
     return obj
+
+
+if __name__ == '__main__':
+
+    import pytz
+
+    print('DATETIME WITHOUT TIMEZONE')
+    datetime_without_timezone = datetime.datetime.now()
+    print("Original:", datetime_without_timezone)
+
+    encoded = encode_datetime(datetime_without_timezone)
+    print("Encoded:", encoded)
+
+    decoded = decode_datetime(encoded)
+    print("Decoded:", decoded)
+
+
+    print('')
+    print('DATETIME WITH TIMEZONE')
+    # datetime_with_timezone = datetime.datetime.now()
+    tmp = pytz.timezone("Europe/Paris").localize(datetime.datetime.now())
+    datetime_with_timezone = tmp.astimezone(pytz.timezone('America/New_York'))
+    print(datetime_with_timezone)
+
+    print("Original:", datetime_with_timezone)
+
+    encoded = encode_datetime(datetime_with_timezone)
+    print("Encoded:", encoded)
+
+    decoded = decode_datetime(encoded)
+    print("Decoded:", decoded)
+
+
+    print('')
+    print('DATE')
+    date = datetime.date(2019, 3, 10)
+    print("Original:", date)
+
+    encoded = encode_datetime(date)
+    print("Encoded:", encoded)
+
+    decoded = decode_datetime(encoded)
+    print("Decoded:", decoded)
-- 
GitLab