2016-02-02 6 views
1

В моем проекте VB.NET, используя JSON.NET, у меня есть JSON из веб-API, который имеет значение, представляющее дату в формате yyyy-MM-ddTHH:mm:ss, и я бы как просто получить эту ценность.JSON.NET: получить конкретное значение даты JSON

Вот более или менее то, что JSON выглядит следующим образом:

{ 
    "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 temp As String = myJsonResult("REQ_DATE") 
' temp = "1/17/2016 12:27:57 PM" 

Мне нужна такая дата, как это было из извлеченного JSON. Я вижу два способа решить эту проблему: конвертируйте ее в yyyy-MM-ddTHH:mm:ss вручную или с помощью регулярного выражения, чтобы напрямую захватить пару ключ-значение - оба из которых у меня не были успешными.

Моя попытка превратить его в 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") 

Моя попытка использовать 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... 

Любые и вся помощь очень ценится.

ответ

2

Я предполагаю, что myJsonResult является JObject, в которую вы загрузили ваш JSON.

Ваша трудность состоит в том, что Json.NET автоматически распознает строки как даты при чтении и конвертирует их в DateTime structs. Затем, когда вы позже сделаете ToString() на токене значения, он возвращается в формате «инвариантной культуры» C#, а не в исходном формате, который в этом случае был ISO 8601. Если вы не хотите этого, вы можете разобрать ваш JSON с помощью 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 

Там нет перегрузки для JObject.Parse(), которая принимает JsonSerializerSettings, так что вам нужно будет использовать DeserializeObject. Этот параметр в конечном итоге распространяется до JsonReader.DateParseHandling.

В качестве альтернативы, если вы в порядке с Json.NET распознавания даты, но всегда, как они должны быть напечатаны в формате ISO 8601, вы можете повторно сериализации маркер JSON, а не просто получить значение строки:

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

Прототип fiddle. Связанный c# question.

+0

Интересно. Мне удалось выполнить эту работу с моим ответом ниже, но это объясняет автоматическое преобразование - и решение более элегантно. – chakeda

1

Когда вы получаете разобранную финиковой строку из Json.NET будет в формате вашей культуры, как показано в коде комментария:

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

Этот формат является «M/d/гггг чч: мм: ss tt ", поэтому используйте этот формат для синтаксического анализа. Но так как в формате для вашей культуры, вы можете позволить проверить DateTime/использовать все известные форматы, используя 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" 

Если вы хотите, чтобы указать формат (это было бы лучше использовать 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 

Дата не имеет формат, так что не может изменить, но оно может отображаться по-разному для настройки культуры. Вы можете отобразить ее так, как вы хотите, это все та же дата:

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")) 
+0

Спасибо - на основании вашего ответа у меня есть это, чтобы работать. В частности, см. Мой ответ ниже. Вместо этого я использовал 'DateTime.Parse' – chakeda

1

Отвечая на мой вопрос. У меня есть работа, просто сделав DateTime.Parse на JObject, а затем сделав ToString в желаемом формате.

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") 

Я использовал ответ dbc в своем коде, поскольку он более изящный.

Смежные вопросы