I had an email this evening about parsing Facebook timestamps in Actionscript 3. The format for timestamps is defined in RFC3339 which as I've discussed previously, is a profile of ISO8601.You'll have come across these before if you've ever worked with Atom feeds.

It seem's Facebook's implementation has been returning an invalid UTC offset of+0000 instead of the more correct Z (for Zulu Time) or +00:00 or -00:00. This inevitably has been causing some parsers to break. Believe it or not this is somewhat of an improvement as they are finally recognising the UTC standard. Until last month you were required to convert timestamps to local Pacific time if you wanted to make a call to the OpenGraph API. Facebook aren't the only company under the delusion that California is the centre of the universe - it's quite common in Silicon Valley. When Macromedia shipped Flash Player 5 it applied US Pacific daylight saving rules to the entire world.

The code below is a revised RFC3339 parser for Actionscript 3. It's written to cope with Facebook's special version of the RFC3339 without going bang. Hopefully you'll find it useful.

function RFC3339toDate( rfc3339:String ):Date
{
  var datetime:Array = rfc3339.split("T");
  var date:Array = datetime[0].split("-");
  var year:int = int(date[0])
  var month:int = int(date[1]-1)
  var day:int = int(date[2])
  var time:Array = datetime[1].split(":");
  var hour:int = int(time[0])
  var minute:int = int(time[1])
  var second:Number 

  // parse offset
  var offsetString:String = time[2]; 
  var offsetUTC:int 
  if ( offsetString.charAt(offsetString.length -1) == "Z" ) 
  {
    // Zulu time indicator
    offsetUTC = 0; 
    second = parseFloat( offsetString.slice(0,offsetString.length-1) )
  }
  else
  {
    // split off UTC offset 
    var a:Array 
    if (offsetString.indexOf("+") != -1) 
    {
      a = offsetString.split("+") offsetUTC = 1
    }
    else if (offsetString.indexOf("-") != -1)
    {
      a = offsetString.split("-") offsetUTC = -1
    }
    else
    {
      throw new Error( "Invalid Format: cannot parse RFC3339 String." )     }

    // set seconds 
    second = parseFloat( a[0] )
    // parse UTC offset in millisceonds 
    var ms:Number = 0 
    if ( time[3] ) 
    {
      ms = parseFloat(a[1]) * 3600000 ms += parseFloat(time[3]) * 60000 
    }
    else
    {
      ms = parseFloat(a[1]) * 60000 } offsetUTC = offsetUTC * ms 
    }

    return new Date( Date.UTC( year, month, day, hour, minute, second) + offsetUTC ); }