Как преобразовать строку времени в time.Time в golang?

Я читаю данные из нескольких таблиц, используя JOIN, CONCAT, GROUP_CONCAT, JSON_OBJECT. Данные считываются в приведенную ниже модель с использованием gorm.

type OrgUserDisPublisherData struct {
    Disciplines datatypes.JSON `json:"disciplines" example:"[]"`
    User        datatypes.JSON `json:"user"`
}

Этот процесс успешно завершен. Но затем, когда я пытаюсь разобрать OrgUserDisPublisherData.Disciplines в другую структуру, которая имеет time.Time типы данных. Я получаю следующую ошибку parsing time "\"2022-11-03 07:08:09.000000\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse " 07:08:09.000000\"" as "T"

Окончательная модель, используемая для десортировки

type Discipline struct {
        Name              string    `json:"name"`
        Code              string    `json:"code"`
        IsPrimary         uint      `json:"isPrimary"`
        IsAligned         uint      `json:"isAligned"`
        IsTrainingFaculty uint      `json:"isTrainingFaculty"`
        AlignmentDate     time.Time `json:"alignmentDate"`
        UnalignmentDate   time.Time `json:"UnalignmentDate"`
        ExpiryDate        time.Time `json:"expiryDate"`
        ExternalId        string    `json:"externalId"`
        Status            string    `json:"status"`
        CreatedAt         time.Time `json:"createdAt"`
        UpdatedAt         time.Time `json:"updatedAt"`
    }

В то же время при вставке данных в таблицы использовалась одна и та же модель, и она не выдает никакой ошибки, связанной со временем. Как я могу обрабатывать время при деупорядочении, независимо от данных, которые присутствуют в свойстве time?

Вы должны объявить свой собственный тип времени с помощью пользовательского маршаллера, если ваш ввод не соответствует RFC-3339. Этот пост может вам помочь: romangaranin.net/posts/2021-02-19-json-time-and-golang

Eelco 13.11.2022 17:43

Альтернативой объявлению нового типа может быть обеспечение того, чтобы значения временной метки в объекте JSON, созданном запросом, имели формат, ожидаемый time.Time's UnmarshalJSON; это вы можете сделать с to_char, например. to_char(created_at, 'YYYY-MM-DDTHH24:MI:SSTZH:TZM').

mkopriva 13.11.2022 17:48
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
2
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема здесь заключается в том, что поведение маршалинга JSON по умолчанию для типов даты/времени в структурах GoLang заключается в использовании строк даты/времени в формате ISO8601.

Это определяется строкой формата в сообщении об ошибке с разделителем T между датой и временем и суффиксом часового пояса. Значения в вашей строке Discipline JSON не соответствуют этому формату, в них отсутствует разделитель T и часовой пояс. Отсюда ошибка.

Если вы можете повлиять на форматирование строки JSON, созданной gorm (не то, с чем я знаком, поэтому не могу сказать, можете ли вы и как это сделать), то самым простым решением было бы убедиться, что ваши поля времени строки JSON отформатированы как строки ISO8601/RFC3339.

Если у вас нет контроля над этим, у вас есть два варианта:

  1. Реализуйте некоторую предварительную обработку JSON через промежуточное звено map[string]any и переформатируйте соответствующие поля. Если форматирование gorm по крайней мере согласовано, то это может быть так же просто, как разбить строку на пробел, удалить последние 3dps из времени, добавить соответствующий часовой пояс (или просто Z, если время UTC), а затем повторно собрать с помощью T разделитель.

  2. Используйте пользовательский тип времени с реализацией json.Marshaller, которая правильно работает со значениями в формате gorm (вам все равно нужно знать, какой часовой пояс применяется к сохраненным значениям, и правильно применять это при сортировке).

Оба они уязвимы для изменения форматирования переменных даты/времени и неправильного использования (отказ от предварительной обработки в случае варианта № 1 и ошибочное использование time.Time вместо пользовательского типа в случае варианта № 2). ).

По этой причине изменение форматированного вывода из gorm было бы для меня предпочтительным подходом, если это возможно.

Самым быстрым решением было отформатировать данные/значение при чтении из БД, как это было предложено @Deltics.

При запросе данных из БД с помощью DATE_FORMAT() я форматирую данные в формате, требуемом go/json

DATE_FORMAT(actual_data, '%Y-%m-%dT%TZ')

Другие вопросы по теме