{"id":4289,"date":"2014-11-05T09:00:36","date_gmt":"2014-11-05T11:00:36","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=4289"},"modified":"2015-06-01T12:21:25","modified_gmt":"2015-06-01T15:21:25","slug":"how-to-serialize-date-and-datetime-without-losing-information","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2014\/11\/how-to-serialize-date-and-datetime-without-losing-information\/","title":{"rendered":"How to serialize Date and DateTime to JSON without losing information"},"content":{"rendered":"
When building APIs, it is pretty common to use JSON as a serialization format. JSON defines serialization for boolean, number and string, but not for date\/datetime values.<\/p>\n
What most serializers do with Date and DateTime values is to use the ISO8601 standard. For example:<\/p>\n
\n# Date format\n2011-07-14\n\n# DateTime format\n2011-07-14T19:43:37+0100\n<\/pre>\nHowever, you should be aware that information is lost when you use the Date format. That happens because a Date value might differ between different timezones. Let me give you an example:<\/p>\n
2011-07-14 T01:00:00Z<\/code> (UTC) from Brazil (UTC-0300) to a service in UTC<\/li>\n- if the time the request was created is exposed as a Date, it would return the value as
2011-07-14<\/code><\/li>\n- but from the client’s perspective in Brazil, the correct date is
2011-07-13<\/code>, since at the moment of that request was issued, the local time in Brazil was 2011-07-13 T22:00:00-0300<\/code><\/li>\n<\/ul>\nIf this information is used only inside your app, within the same timezone, you would have no problems. But, if you need to make this information available through a public API, one of your API’s consumers might recover an incorrect value.<\/p>\n
So, from this experience, any date value that will be shared and consumed by different clients should be represented as date time with explicit timezone or using the Unix time format<\/strong>. That way, it is up to the client to treat the data properly.<\/p>\nHere is an example of an API that returns a subscription period in the right way:<\/p>\n
{\n period_start_date: 1409175049, # Unix time\n period_end_date: 2014-09-27T18:30:49-0300 # ISO8601\n}\n\n# Time.at(1409175049)\n# DateTime.parse(\u201c2014-09-27T18:30:49-0300\u201d)\n<\/code><\/pre>\nThe options above have the advantage that both are unambiguous and sortable. You may choose between one or another based on the fact that the timezone option is easier for human comprehension. But remember that Timezones are a presentation-layer problem<\/a>, so if you just need to pass data around, Unix time is preferable.<\/p>\nHave you ever had this serialization problem or any other that caused information to be lost? If you have questions or any experience to share, please, leave a comment below.<\/em><\/p>\n\n<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"When building APIs, it is pretty common to use JSON as a serialization format. JSON defines serialization for boolean, number and string, but not for date\/datetime values. What most serializers do with Date and DateTime values is to use the ISO8601 standard. For example: # Date format 2011-07-14 # DateTime format 2011-07-14T19:43:37+0100 However, you should … \u00bb<\/a><\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[226,228,229,227],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4289"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=4289"}],"version-history":[{"count":14,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4289\/revisions"}],"predecessor-version":[{"id":4709,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/4289\/revisions\/4709"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=4289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=4289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=4289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}