Yet another JSON and DATE question

First off, sorry if this has already been asked I missed it in my searching.

The back story:
I am working on becoming more OO vs Procedural along with learning the use of JSON vs Databases (when needed).

I am populating a class by parsing a JSON file. A few parameters of my class are of type date.
myPredefinedClass
item as string
status as string
created as date
updated as date

Dim myClass as new myPredefinedClass     

myClass.status = jItem.Child("fields").Child("status").value("name")
myClass.created = jItem.Child("fields").value("created")
myClass.updated = jItem.Child("fields").value("updated")    

Here’s the question:
When populating the data properties of the class, is there a more streamlined way of casting the string to a date inline? The following throws an “UnupportedFormatException”.

myClass.created = Jitem.Child("fields").value("created").DateValue

I am familiar with parsedate() and can create methods to fulfill. Again, I am still learning the OO way of doing things and need some guidance on best practices and syntax.

thanks!

Did you create the json file? What do the values look like in it?

I am pulling the JSON from using an API to Atlassian’s JIra.
the string values for the dates look like : “2013-10-07T12:06:59.000-0500”

        "some item" : "some value",
        "updated" : "2013-10-07T14:46:53.000-0500",
        "some other value" : "some other value"

That’s a standard format, but not one that’s recognized natively by Xojo. It’s easy enough to parse though. Create a function out of this:

dim rx as new RegEx
rx.SearchPattern = "(?mi-Us)^(?'date'\\d{4}-\\d{2}-\\d{2})T(?'time'\\d{2}:\\d{2}:\\d{2})\\.\\d{3}(?'gmt'[-+]\\d+)$"

dim d as Date
dim match as RegExMatch = rx.Search(dateValue)
if match IsA RegExMatch then
  d = new Date
  d.GMTOffset = match.SubExpressionString(3).Val / 100
  d.SQLDateTime = match.SubExpressionString(1) + " " + match.SubExpressionString(2)
end if

return d

Edit: GMT has to be divided by 100.

Thanks Kem this works!

Does this imply the answer to the question is “create a method to fulfill”?

My initial attempt was a method doing mid() string parsing and building the date format.
(I need to tinker with RegEx more.)

Thanks!

That would be best. This is the ISO 8661 format, if I’m not mistaken, so a global method to parse that would be useful.

I’ve had this one laying around since 2006 / 2007 :stuck_out_tongue:

ParseISO8601Date(dateString As String) as Date
 // http://www.w3.org/TR/NOTE-datetime
  
  Dim year, month, day, hour, minute, second, fractionOfASecond, gmtOffset As Integer
  Dim stream As New BinaryStream( dateString )
  
  year = stream.read( 4 ).val()
  If stream.eof Then GoTo done
  
  If stream.read( 1 ) <> "-" Then GoTo invalid
  month = stream.read( 2 ).val()
  If stream.eof Then GoTo done
  
  If stream.read( 1 ) <> "-" Then GoTo invalid
  day = stream.read( 2 ).val()
  If stream.eof Then GoTo done
  
  If stream.read( 1 ) <> "T" Then GoTo invalid
  hour = stream.read( 2 ).val()
  If stream.read( 1 ) <> ":" Or stream.eof Then GoTo invalid
  minute = stream.read( 2 ).val()
  If stream.read( 1 ) <> ":" Or stream.eof Then GoTo invalid
  second = stream.read( 2 ).val()
  If stream.eof Then GoTo invalid
  
  If stream.read( 1 ) = "." Then
    // we have a fraction of a second
    Dim char As String = stream.read( 1 )
    
    While char.asc >= 48 And char.asc <= 58
      fractionOfASecond = fractionOfASecond * 10 + char.val()
      char = stream.read( 1 )
    Wend
  End If
  stream.position = stream.position - 1
  
  If stream.read( 1 ) = "Z" Then
    gmtOffset = 0
  Else
    // back up again
    stream.position = stream.position -1
    gmtOffset = stream.read( 3 ).val() * 100
    If stream.read( 1 ) <> ":" Or stream.eof Then GoTo invalid
    
    gmtOffset = gmtOffset + stream.read( 2 ).val()
  End If
  
  done:
  Dim d As New Date()
  d.year = year
  d.month = month
  d.day = day
  d.hour = hour
  d.minute = minute
  d.second = second
  d.GMTOffset = gmtOffset / 100
  
  Return d
  
  invalid:
  Raise New UnsupportedFormatException
end sub
1 Like

ISO date formats are soooooo much fun :stuck_out_tongue:

I’m not in a position to test but I think you have to set the GMT first or the other values will change.

it a standard format that very people (or very few people I ran across) use. When I was reading stuff out of Jira for a client I wrote a date parser that would take the Jira date string in and return a date object with the various fields filled in. I also wrote a parse that took a date and created the jira date string.

either is not hard to do, just have to sit down and write it.

must set the date object to GMTOffset=0 before setting the values OR they will change.

Thanks guys!

The good, I had the answer to my question when I began. The bad, I have to figure out time to just sit down and do it.