Преобразование метки времени в формате JSON в время Голанга. Время - PullRequest
0 голосов
/ 12 марта 2019

У меня есть строка даты и времени в формате json со следующим форматом

 /Date(315513000000+0530)/ 

Я хотел бы преобразовать это в формат golangs time.Time. Я попытался передать эту строку в функцию ниже

func parseDateField(dateInput string) (int64, error) {
    startIdx := strings.Index(dateInput, "(")
    if startIdx == -1 {
        return 0, errors.New("Error parsing quote Date. '(' symbol not found")
    }

    endIdx := strings.Index(dateInput, "+")
    if endIdx == -1 {
    return 0, errors.New("Error parsing quote Date. '+' symbol not found")
     }
    dateStr := dateInput[startIdx+1 : endIdx]
    date, err := strconv.ParseInt(dateStr, 10, 64)
    if err != nil {
        fmt.Printf(" err : \n %+v \n", err)
        return 0, err
     }
     tm := time.Unix(date, 0)
     fmt.Printf("\n time  : \n %+v \n", tm)
     dateAsEpoch := int64(date / 1000)
     fmt.Printf("\n dateAsEpoch  : \n %+v \n", dateAsEpoch)
     return dateAsEpoch, nil
}

Я получаю следующие выводы

 time  : 
 11968-03-18 01:30:00 +0530 IST 


 dateAsEpoch  : 
 315513000 

Я предполагаю, что синтаксический анализ не выполнен правильно - что я делаю неправильно?

1 Ответ

3 голосов
/ 12 марта 2019

Этот формат времени, по-видимому, представляет собой прошедшие миллисекунды с начала эпохи и 4-значный сдвиг зоны со знаком (час и мин).

Самый простой вариант - использовать fmt.Sscanf() для анализаэто, что-то вроде этого:

_, err = fmt.Sscanf(s, "/Date(%d+%02d%02d)/", &ms, &zoneHour, &zoneMin)

Конечно, если смещение зоны отрицательное, формат не будет совпадать.Это может быть обработано второй попыткой синтаксического анализа: + заменяется на - в строке формата.

Если у вас есть ms, умножьте его на миллион, чтобы получить наносекунды, чтобы выможет передать это time.Unix() (допустимо передавать значение наносекунды за пределы диапазона [0, 999999999]).

Последнее, что вы можете использовать time.FixedZone()чтобы получить зону, соответствующую смещению зоны на входе, а затем с помощью Time.In() «переключиться» на эту зону.

Обратите внимание, что миллисекунды с начала эпохинезависимый от зоны (указывается в зоне UTC).Переключение на смещение зоны источника требуется только для того, чтобы при печати времени (или при обращении к его «полям», таким как год, месяц, день), вы увидели предполагаемые дату и время, поскольку они будут другими в другой зоне.,Например, у вас есть экземпляр, он обозначает дату 1980-01-01 и 0 раз в день.Без зоны +0530, это был бы другой день, это было бы 1979-12-31 18:30:00 +0000 UTC.

Вот пример, делающий это:

func parse(s string) (t time.Time, err error) {
    var ms int64
    var zhour, zmin int

    if _, err = fmt.Sscanf(s, "/Date(%d+%02d%02d)/", &ms, &zhour, &zmin); err != nil {
        if _, err = fmt.Sscanf(s, "/Date(%d-%02d%02d)/", &ms, &zhour, &zmin); err != nil {
            return time.Time{}, fmt.Errorf("Failed to parse: %v", err)
        }
        zhour = -zhour
        zmin = -zmin
    }

    t = time.Unix(0, ms*1000000)
    t = t.In(time.FixedZone("", zhour*3600+zmin*60))
    return
}

Тестирование:

fmt.Println(parse("/Date(315513000000+0530)/"))
fmt.Println(parse("/Date(315513000000-0530)/"))
fmt.Println(parse("invalid"))

Вывод (попробуйте на Go Playground ):

1980-01-01 00:00:00 +0530 +0530 <nil>
1979-12-31 13:00:00 -0530 -0530 <nil>
0001-01-01 00:00:00 +0000 UTC Failed to parse: input does not match format
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...