Конвертировать дату JSON в формат ММ / ДД / ГГГГ?

#json #vba #date #excel-2010

#json #vba #Дата #excel-2010

Вопрос:

Мой клиент получает электронную таблицу с несколькими столбцами, один из которых является «датой». Получается, что только дата отформатирована как Date(1292291582263-0700) (похоже, дата в формате JSON).

Мне нужно преобразовать и работать с этой датой JSON в формате ММ / ДД / ГГГГ в другом месте кода этой таблицы (VBA).

Кто-нибудь знает, как разобрать и преобразовать этот формат даты JSON в формат MM / DD / ГГГГ? Я прочитал множество решений по SO, которые находятся на Javascript, C # или ASP.NET и т.д. Но все, с чем мне нужно работать, это Excel 2010 и код VBA для этого проекта. Есть ли способ получить читаемый формат, который мне нужен?

Комментарии:

1. В JSON нет типа даты. Смотрите боковую панель справа: json.org

2. @Matt: Хорошо, но нет ли какого-нибудь способа преобразовать эту строку в читаемый формат даты (без использования Javascript и т.д.)? Просто функция, написанная от руки или что-то в этомроде?

Ответ №1:

Миллисекундное время эпохи со смещением / -?

 Const test = "1292291582263-0700"

Dim dt As String: dt = Left$(test, 13)
Dim off As String: off = Mid$(test, 14)

Dim d As Date: d = DateAdd("s", CCur(dt) / 1000, "01/01/1970")
Debug.Print d
<<< 14/12/2010 01:53:02 

d = DateAdd("h", Left$(off, 3), d)
d = DateAdd("n", Right$(off, 2), d)
Debug.Print d
<<< 13/12/2010 18:53:02 
  

Ответ №2:

Эта функция обрабатывает дату до 1971-01-01 и некоторую проблему с переполнением.

 Public Function Convert_Microsoft_Json_Date_To_Date(strMicrosoftDate As String) As Date
'Convert_Microsoft_Json_Date_To_Date("/Date(-2208970800000-0530)/") => 1900-01-01
'Convert_Microsoft_Json_Date_To_Date("/Date(2208970800000-0530)/") => 2039-12-31 14:00:00
Dim strProcedureName As String: strProcedureName = "Convert_Microsoft_Json_Date_To_Date"
Dim lngDateNumber As Long
Dim strOffsetSign As String
Dim strOffsetHours As String
Dim strOffsetMinutes As String
Dim dteDateNoOffset As Date
Dim dteRealDate As Date
Dim curSecondToAdd As Currency '  or -
Dim curSecondLeft As Currency
Dim curSecondMax As Currency
Dim IsOffsetExist As Boolean

On Error GoTo err_

strMicrosoftDate = Replace(strMicrosoftDate, "/", "")
strMicrosoftDate = Replace(strMicrosoftDate, "(", "")
strMicrosoftDate = Replace(strMicrosoftDate, ")", "")
strMicrosoftDate = Replace(strMicrosoftDate, "Date", "")

strOffsetSign = Left(Right(strMicrosoftDate, 5), 1)
strOffsetHours = Left(Right(strMicrosoftDate, 4), 2)
strOffsetMinutes = Right(strMicrosoftDate, 2)

IsOffsetExist = strOffsetSign = " " Or strOffsetSign = "-"

If IsOffsetExist Then
    'Remove the offset part if exist
    strMicrosoftDate = Left(strMicrosoftDate, Len(strMicrosoftDate) - 5)
End If
curSecondMax = 1000000000# 'if curSecondToAdd is to high we get overflow, and I do it in 2 step below to get my date
curSecondToAdd = CCur(strMicrosoftDate) / 1000 'Convert miliseconds to seconds

If Abs(curSecondToAdd) > curSecondMax Then
    If curSecondToAdd >= 0 Then
        dteDateNoOffset = DateAdd("s", curSecondToAdd - curSecondMax, DateSerial(1970, 1, 1))
        dteDateNoOffset = DateAdd("s", curSecondMax, dteDateNoOffset)
    Else
        dteDateNoOffset = DateAdd("s", curSecondToAdd   curSecondMax, DateSerial(1970, 1, 1))
        dteDateNoOffset = DateAdd("s", -curSecondMax, dteDateNoOffset)
    End If
Else

    dteDateNoOffset = DateAdd("s", curSecondToAdd, DateSerial(1970, 1, 1))
End If

'Debug.Print "Date no offset: " amp; dteDateNoOffset

If IsOffsetExist Then
    dteRealDate = DateAdd("h", CInt(strOffsetSign amp; strOffsetHours), dteDateNoOffset)
    dteRealDate = DateAdd("n", CInt(strOffsetSign amp; strOffsetMinutes), dteRealDate)
Else
    dteRealDate = dteDateNoOffset
End If
'Debug.Print "Date real: " amp; dteRealDate

Convert_Microsoft_Json_Date_To_Date = dteRealDate

err_exit:

    Exit Function


err_:
Select Case Err.Number

    Case Else
        MsgBox Err.Description amp; " | " amp; Err.Number amp; vbCrLf amp; "Procedure: " amp; strProcedureName amp; IIf(Erl <> 0, vbCrLf amp; "Ligne: " amp; Erl, ""), vbCritical
        Resume err_exit
        Resume
End Select
End Function
  

Комментарии:

1. Пожалуйста, включите объяснение в свой ответ, а не в качестве комментария.