15
$\begingroup$

Does Mathematica have a built-in function to convert ISO 8601 formatted date strings (e.g. 2012-01-04T00:00:00) to a date list?

ISO 8601 strings come in a variety of formats:

Date alone: 2012-12-03
Combined date and time: 2012-12-03T22:02
Combined date and time with time zone: 2012-12-03T22:02:47.23+01

On top of that individual components can be omitted (see the Wiki page). I am looking for a solution that covers the whole ISO 8601 standard.

$\endgroup$
  • $\begingroup$ Unfortunately I think you need to roll your own in that case. $\endgroup$ – Szabolcs Dec 3 '12 at 21:12
  • 2
    $\begingroup$ Whhooaaa, I'm just realizing you are the sakra! The one who was so kind to implement a findMathematica for cmake ;-) You cannot imagine how easy life is with your tool. $\endgroup$ – halirutan Dec 4 '12 at 1:18
  • $\begingroup$ A July 2015 blog post says the Wolfram Language is finally getting native ISO 8601 support. $\endgroup$ – duozmo Oct 16 '15 at 21:42
6
$\begingroup$

You can use JLink (as already mentioned while I read JavaDoc). Searching StackOverflow brings up this highly voted answer

Converting ISO8601-compliant String to java.util.Date

I don't know whether it covers the whole standard but this works out of the box. If this is not sufficient, you can use an equivalent piece of code written for Joda Time

Needs["JLink`"]

ParseDateString[date_String] := JavaBlock[
  InstallJava[];
  LoadJavaClass["javax.xml.bind.DatatypeConverter", 
   StaticsVisible -> True];
  DateList[
   javax`xml`bind`DatatypeConverter`parseDateTime[date]@getTime[]@toString[]
  ]
]

This uses the DataypeConverter class which is available without in standard Java 6. It converts it into a standard date string which can then be used with DateList.

ParseDateString["2010-01-01T12:00:00Z"]

(* {2010, 1, 1, 13, 0, 0.} *)
$\endgroup$
  • $\begingroup$ Does this cover the whole ISO 8601 standard? The o/p wrote: "I am looking for a solution that covers the whole ISO 8601 standard." $\endgroup$ – Andreas Lauschke Dec 3 '12 at 23:20
  • $\begingroup$ Probably not, but I want a working example here. To put another jar in the classpath and write your own method is easy from this point IMO. $\endgroup$ – halirutan Dec 3 '12 at 23:36
5
$\begingroup$

As of Mathematica 10.2, DateString and DateObject support this format directly. For example:

In[1]:= DateObject["2015-09-17T03:12:44"]
Out[1]= DateObject[{2015, 9, 17}, TimeObject[{3, 12, 44.}, TimeZone -> -4.],
         TimeZone -> -4.]
$\endgroup$
2
$\begingroup$

Use Joda Time with JLink. Joda is fully 8601-compliant, and with JLink the whole Java universe is immediately at your fingertips from M.

I've posted a few replies in this forum using Joda Time, for example Faster alternatives for DayOfWeek

where I've mentioned that Joda Time is fully 8601-compliant.

$\endgroup$
1
$\begingroup$

I want to build upon @halirutan answer.

The reason why I need to build upon the answer is DatatypeConverter`parseDateTime actually returns in the following format "Mon Mar 10 21:24:10 GMT+08:00 2014", and DateList[] can't automatically interpret the returned date

Hence, I need to provide the explicit format to DateList[] to make it work in Mathematica. The explicit format is "{"DayName"," ","MonthName"," ","Day"," ", "Hour",":","Minute",":","Second"," GMT+08:00 ", "Year"}"

Please take note of the Time Zone portion. My time zone is GMT+08:00, hence I hard coded it in the explicit format. Most likely you need to update to your own time zone for it to work successfully. For example, your time zone is GMT-08:00 if you are in USA West Coast.

Needs["JLink`"]

ParseDateString[date_String] := JavaBlock[
  InstallJava[];
  LoadJavaClass["javax.xml.bind.DatatypeConverter", 
   StaticsVisible -> True];
  DateList[{
   javax`xml`bind`DatatypeConverter`parseDateTime[date]@getTime[]@toString[],
   {"DayName", " ", "MonthName", " ", "Day", " ", "Hour", ":", "Minute",":", "Second", " GMT+08:00 ", "Year"}}
  ]
]

ParseDateString["2014-03-10T09:24:10.000-04:00"]

And the result will be

{2014, 3, 10, 21, 24, 10.}
$\endgroup$
1
$\begingroup$

Looks like AbsoluteTime might get you close. My examples here don't include the final 04:00.

In[1]:= AbsoluteTime["2014-07-31T10:19:08.985"]
Out[1]= 3.615790748985000*10^9

In[2]:= ToExpression /@ 
 StringSplit["2014-07-31T10:19:08.985", ("-" | "T" | ":")]
Out[2]= {2014, 7, 31, 10, 19, 8.985}

In[3]:= AbsoluteTime@%
Out[3]= 3.615790748985000*10^9
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.