1

In my VB.NET project, using JSON.NET, I've got a JSON from a Web API that has a value representing a date in the yyyy-MM-ddTHH:mm:ss format, and I'd like to simply get that value.

Here's more or less what the JSON looks like:

{
    "REQ_DATE": "2016-01-17T12:27:57",
    "REQ_TYPE": "Vacation",
    "HOURS": 500.0,
    "LEAVE_TIME": "8:00 AM",
    "LEAVE_DATE": "2016-01-23T00:00:00",
    "DUE_TIME": "8:00 AM",
    "DUE_DATE": "2016-01-24T00:00:00",
}

So I should just serialize it and do what I will with the value, right? However, when I put that key-value in a variable, the date format is automatically changed!

Dim temp As String = myJsonResult("REQ_DATE")
' temp = "1/17/2016 12:27:57 PM"

I need to have that Date as it was from the retrieved JSON. I see two ways to go about this problem: converting it to yyyy-MM-ddTHH:mm:ss manually, or using regex to directly grab the key-value pair - both of which I have had no success with.

My attempt to convert it into DateTime:

Dim tempDateTime As DateTime = DateTime.ParseExact(myJsonResult("REQ_DATE").ToString,"yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture)
' Error: String is not Recognized as valid DateTime
Dim myDesiredResult As String = tempDateTime.ToString("yyyy-MM-ddTHH:mm:ss")

My attempt to use Regex:

Dim regex As Regex = New Regex("""REQ_DATE"": ""([\d\w]*)""")
Dim match As Match = regex.Match(myJsonAsString)
If match.Success Then
   Dim myDesiredResult As String = match.Groups(1).Value
End If
' match is empty... 

Any and all help is greatly appreciated.

3 Answers 3

2

I assume that myJsonResult is a JObject into which you have loaded your JSON.

Your difficulty is that Json.NET automatically recognizes strings as dates when reading and converts them to DateTime structs. Then when you later do ToString() on the value token, it comes back in c#'s "invariant culture" format rather than the original format, which in this case was ISO 8601. If you do not want this behavior, you can parse your JSON using JsonSerializerSettings.DateParseHandling = DateParseHandling.None:

        Dim jsonString = "{'REQ_DATE':'2016-01-17T12:27:57','REQ_TYPE':'Vacation','HOURS':500.0,'LEAVE_TIME':'8:00 AM','LEAVE_DATE':'2016-01-23T00:00:00','DUE_TIME':'8:00 AM','DUE_DATE':'2016-01-24T00:00:00'}"
        Dim settings = New JsonSerializerSettings() With { _
            .DateParseHandling = DateParseHandling.None _
        }
        Dim myJsonResult = JsonConvert.DeserializeObject(Of JObject)(jsonString, settings)
        Dim dateValue = myJsonResult("REQ_DATE")
        Dim dateString = CType(dateValue, String) 'Value is 2016-01-17T12:27:57

There's no overload to JObject.Parse() that takes a JsonSerializerSettings, so you would need to use DeserializeObject. This setting eventually gets propagated to JsonReader.DateParseHandling.

Alternatively, if you are OK with Json.NET recognizing dates but would always like them to be printed in ISO 8601 format, you can re-serialize the token to JSON rather than just getting the string value:

        Dim dateValue = myJsonResult("REQ_DATE")
        Dim dateString = JsonConvert.SerializeObject(dateValue).Trim(""""c) 'Value is 2016-01-17T12:27:57

Prototype fiddle. Related c# question.

Sign up to request clarification or add additional context in comments.

1 Comment

Interesting. I've managed to make this work with my answer below, but this explains the automatic conversion - and the solution is more elegant.
1

When you get the parsed date-string from JSON.NET it will be in your culture's format as shown in your code comment:

Dim temp As String = myJsonResult("REQ_DATE")
' temp = "1/17/2016 12:27:57 PM"

That format is "M/d/yyyy HH:mm:ss tt" so use that format for parsing. But since it is in a format for your culture, you can let DateTime check/use all the known formats using TryParse:

Dim dt As DateTime
Dim temp As String = jobj("REQ_DATE").ToString

If DateTime.TryParse(temp, dt) Then
    'dt is good to use!
    Console.WriteLine(dt.ToString)
    ' Prints: 1/17/2016 12:27:57 PM
End If

Dim myDesiredResult As String = dt.ToString("yyyy-MM-ddTHH:mm:ss")
' result: "2016-01-17T12:27:57"

If you want to specify the format (it would be better to use TryParseExact):

dt = DateTime.ParseExact(temp, "M/d/yyyy HH:mm:ss tt",
         CultureInfo.InvariantCulture)
Console.WriteLine(dt.ToString())
' Also prints: 1/17/2016 12:27:57 PM

Dates dont have a format, so it cant change, but it may display differently for your culture settings. You can display it any way you want, it is still the same date:

Console.WriteLine(dt.ToString("HH yyyy MM mm dd"))
Console.WriteLine(dt.ToString("yyyy-MM-ddTHH:mm:ss"))
Console.WriteLine(dt.ToString("MM/d/yyyy HH:mm:ss tt"))

1 Comment

Thanks - based on your answer, I've got it to work. Specifically, see my answer below. I used DateTime.Parse instead
1

Answering my own question. I've got it to work simply by doing DateTime.Parse on the JObject, then doing ToString to my desired format.

    Dim temp As String = myRequest("REQ_DATE").ToString
    Dim tempDateTime As DateTime = DateTime.Parse(temp.ToString)
    Dim myDesiredResult As String = tempDateTime.ToString("yyyy-MM-ddTHH:mm:ss") 

I used dbc's answer in my code as it is more elegant.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.