Repository: fossasia/open-event-server

Issue:
Convert API datetime format to iso8601
https://en.wikipedia.org/wiki/ISO_8601

Example - 2016-06-06T11:22:33+0800

To incorporate timezone in the datetime value, it should be converted to a more rich format like ISO8601.
There is a nice library for it. http://pyiso8601.readthedocs.io/en/latest/



Discussion:
Sounds good.

Postgres doesn't store timezone aware datetime's with the timezone but [converts them to UTC](http://www.postgresql.org/docs/8.3/interactive/datatype-datetime.html#DATATYPE-TIMEZONES) and then stores it. That being said, only option we have is to store timezone as a separate field. Now when timezone is being stored as a separate field, it is better to return local time in the API and it can be combined with timezone to return the full time. This is being done in #1091 

Btw, iso8601 uses T as a separator between date and time so it makes the dates _URL friendly_ (useful for filtering in GET APIs). I will implement that in this issue. I will also keep the API **backwards compatible** to support space-separated date and time. The new format of datetime will be - 2016-06-06T11:22:33


Resolving patch:
diff --git a/open_event/api/events.py b/open_event/api/events.py
--- a/open_event/api/events.py
+++ b/open_event/api/events.py
@@ -94,6 +94,8 @@ def fix_payload(self, data):
         data['end_time'] = EVENT_POST['end_time'].from_str(data['end_time'])
         data['closing_datetime'] = EVENT_POST['closing_datetime'].from_str(
             data['closing_datetime'])
+        data['schedule_published_on'] = EVENT_POST['schedule_published_on'].from_str(
+            data['schedule_published_on'])
         return data
 
     def create(self, data, url):
diff --git a/open_event/api/helpers/custom_fields.py b/open_event/api/helpers/custom_fields.py
--- a/open_event/api/helpers/custom_fields.py
+++ b/open_event/api/helpers/custom_fields.py
@@ -116,16 +116,18 @@ class DateTime(CustomField):
     Custom DateTime field
     """
     __schema_format__ = 'date-time'
-    __schema_example__ = '2016-06-06 11:22:33'
-    dt_format = '%Y-%m-%d %H:%M:%S'
+    __schema_example__ = '2016-06-06T11:22:33'
+    dt_format = '%Y-%m-%dT%H:%M:%S'
 
     def to_str(self, value):
         return None if not value \
             else unicode(value.strftime(self.dt_format))
 
     def from_str(self, value):
-        return None if not value \
-            else datetime.strptime(value, self.dt_format)
+        if not value:
+            return None
+        value = value.replace(' ', 'T', 1)
+        return datetime.strptime(value, self.dt_format)
 
     def format(self, value):
         return self.to_str(value)
@@ -139,7 +141,7 @@ def validate(self, value):
             else:
                 self.to_str(value)
         except Exception:
-            self.validation_error = 'Incorrect format of datetime used in %s field. Should be YYYY-MM-DD HH:MM:SS'
+            self.validation_error = 'Incorrect format of datetime used in %s field. Should be YYYY-MM-DDTHH:MM:SS.'
             return False
         return True
 


Test patch:
diff --git a/tests/api/utils_post_data.py b/tests/api/utils_post_data.py
--- a/tests/api/utils_post_data.py
+++ b/tests/api/utils_post_data.py
@@ -5,7 +5,7 @@
 POST_EVENT_DATA = {
     "color": "red",
     "email": "event@gmail.com",
-    "end_time": "2016-05-30 12:12:43",
+    "end_time": "2016-05-30T12:12:43",
     "timezone": "UTC",
     "latitude": 0,
     "location_name": "TestEvent",
@@ -15,15 +15,16 @@
     'event_url': "http://site.com",
     'background_url': "http://imgur.com/image.png",
     'description': "blah blah",
-    "start_time": "2016-05-25 12:12:43",
-    "closing_datetime": "2016-05-22 12:12:43",
+    "start_time": "2016-05-25T12:12:43",
+    "closing_datetime": "2016-05-22T12:12:43",
     "organizer_name": "FOSSASIA",
     "organizer_description": "Promoting Open Source culture around the world",
     "state": "pending",
     "type": "Conference",
     "topic": "Science & Technology",
     "privacy": "public",
-    "ticket_url": "http://site.com/tickets"
+    "ticket_url": "http://site.com/tickets",
+    "schedule_published_on": None
 }
 
 POST_MICROLOCATION_DATA = {
@@ -37,10 +38,10 @@
 POST_SESSION_DATA = {
     "short_abstract": "TestSession",
     "long_abstract": "TestSession",
-    "end_time": "2016-05-30 09:47:37",
+    "end_time": "2016-05-30T09:47:37",
     "microlocation_id": None,
     "speaker_ids": [],
-    "start_time": "2016-05-30 08:47:37",
+    "start_time": "2016-05-30T08:47:37",
     "subtitle": "TestSession",
     "comments": "Comments",
     "title": "TestSession",