Parsing ISO dates with Flex and ActionScript

The following example shows how you can parse an ISO format date (for more information, see http://www.w3.org/TR/NOTE-datetime) and convert it into a Date object in ActionScript using the String class’s replace() method and the static Date.parse() method.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/02/parsing-iso-dates-with-flex-and-actionscript/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();">
 
    <mx:Script>
        <![CDATA[
            [Bindable]
            private var d:Date;
 
            private function init():void {
                var isoStr:String = "2008-01-25T06:14:23Z";
                d = isoToDate(isoStr);
                formHeading.label = isoStr;
            }
 
            private function isoToDate(value:String):Date {
                var dateStr:String = value;
                dateStr = dateStr.replace(/\-/g, "/");
                dateStr = dateStr.replace("T", " ");
                dateStr = dateStr.replace("Z", " GMT-0000");
                return new Date(Date.parse(dateStr));
            }
        ]]>
    </mx:Script>
 
    <mx:Form>
        <mx:FormHeading id="formHeading" />
        <mx:FormItem label="toString():">
            <mx:Label text="{d.toString()}" />
        </mx:FormItem>
        <mx:FormItem label="toLocaleString():">
            <mx:Label text="{d.toLocaleString()}" />
        </mx:FormItem>
        <mx:FormItem label="toUTCString():">
            <mx:Label text="{d.toUTCString()}" />
        </mx:FormItem>
    </mx:Form>
 
</mx:Application>

View source is enabled in the following example.

A big thanks to Jon for helping me with the bug in my time-zone conversion.

14 thoughts on “Parsing ISO dates with Flex and ActionScript

  1. Thanks for the code – a real life saver!

    The only thing your function doesn’t deal with is the “null” ISO date: 0001-01-01T00:00:00. I would have expected this function to return a null Date object if it were passed this String.

    public static function parseIsoDate(dateStr:String):Date
    {
    	dateStr = dateStr.replace(/-/g, "/");
    	dateStr = dateStr.replace("T", " ");
    	dateStr = dateStr.replace("Z", " GMT-0000");
    	const i:Number = Date.parse(dateStr);
    
    	if (i < 0)
    	{
    		return null;
    	}
    	else
    	{
    		return new Date(i);
    	}
    }
    
  2. David, Peter

    From my experience, if you can’t guarantee the given parameter dateStr is a valid date you should check for NaN using isNaN(i).
    Many thanks for the useful example!

    Have fun
    Robert

  3. Thank you! Thank you! Thank you!

    I’ll add the following for fellow Force.com developers who encounter difficulties converting from the SFDC (Salesforce.com) DateTime datatype to the Flex Date datatype.

    SFDC stores ISO format with milliseconds (i.e. “2009-09-22T15:00:00.000Z”) which I had to strip out before the above code would work

  4. Thank You very much. I got this isodate format from my C#( + Fluorine) webservice. I’ve been looking for the solution since yesterday.

  5. Hi, I had the big problem, that DateUtil.parseW3CDTF() failed when parsing a lot of dates. Then I found your solution and it solved my problem. Not only that but it is also way faster!

    But I have one improvement, that I would suggest: I have to work with GMT offsets, so I rewrote the parser like that:


    dateString = dateString.replace(/(\d{4,4})\-(\d{2,2})\-(\d{2,2})/g, "$1/$2/$3");
    dateString = dateString.replace("T", " ");
    dateString = dateString.replace(/(\+|\-)(\d+):(\d+)/g, " GMT$1$2$3");
    dateString = dateString.replace("Z", " GMT-0000");

    Maybe it’s useful for anybody ;-)

    -Dani

  6. For those that want to handle milliseconds, I modified the code a bit to add them in later.

    private function convertISOToDate() : Date 
    {
        var date : Date;
        var dateStr : String = timestamp;
        var milliseconds : Number = Number( dateStr.match( /.[0-9]+/ ) ) * 1000;
        dateStr = dateStr.replace(/-/g, "/");
        dateStr = dateStr.replace("T", " ");
        dateStr = dateStr.replace( /.[0-9]+/, " " );
        dateStr = dateStr.replace("Z", " GMT-0000");
        date = new Date( Date.parse( dateStr ) );
        date.setMilliseconds( milliseconds );
        return date;
    }
    1. Seems that the mx.formatters.DateFormatter class can parse an ISO date if you trim off the last 6 characters (i.e. the time zone offset). Here’s a real simple utility class:
      <code>
      package fleetcycle.cp.util
      {
      import mx.formatters.DateFormatter;

      public final class DateFormatterUtil
      {
      public static function parseISOString(str:String):Date
      {
      if (str != null && str.length > 0)
      {
      str = str.substring(0, str.length – 6);
      return DateFormatter.parseDateString(str)
      } else
      {
      return null;
      }
      }
      }
      }
      <code>
      And here is a FlexUnit test method that verifies it works:
      <code>
      [Test]
      public function test_parse_standardutil():void
      {
      var dt:Date = DateFormatterUtil.parseISOString(“2010-03-20T06:30:23-05:00”);
      assertEquals(2010, dt.fullYear);
      assertEquals(2, dt.month);
      assertEquals(20, dt.date);
      assertEquals(6, dt.hours);
      assertEquals(30, dt.minutes);
      assertEquals(23, dt.seconds);
      }
      <code>

  7. Hi,

    i have a problem face from last day.

    The problem is that i want to run a countdown Timer. The timer is start from two dates
    1. current date (as New Date()).
    2. the immediate Monday (as new Date(“Mon Jan 17 2011″))

    The problem is with 2nd date.

    How i dynamically find the next Monday date ?.

    Thanks and welcome for Help.

Comments are closed.