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

Проблема здесь заключается в том, что поведение маршалинга JSON по умолчанию для типов даты/времени в структурах GoLang заключается в использовании строк даты/времени в формате ISO8601.
Это определяется строкой формата в сообщении об ошибке с разделителем T между датой и временем и суффиксом часового пояса. Значения в вашей строке Discipline JSON не соответствуют этому формату, в них отсутствует разделитель T и часовой пояс. Отсюда ошибка.
Если вы можете повлиять на форматирование строки JSON, созданной gorm (не то, с чем я знаком, поэтому не могу сказать, можете ли вы и как это сделать), то самым простым решением было бы убедиться, что ваши поля времени строки JSON отформатированы как строки ISO8601/RFC3339.
Если у вас нет контроля над этим, у вас есть два варианта:
Реализуйте некоторую предварительную обработку JSON через промежуточное звено map[string]any и переформатируйте соответствующие поля. Если форматирование gorm по крайней мере согласовано, то это может быть так же просто, как разбить строку на пробел, удалить последние 3dps из времени, добавить соответствующий часовой пояс (или просто Z, если время UTC), а затем повторно собрать с помощью T разделитель.
Используйте пользовательский тип времени с реализацией json.Marshaller, которая правильно работает со значениями в формате gorm (вам все равно нужно знать, какой часовой пояс применяется к сохраненным значениям, и правильно применять это при сортировке).
Оба они уязвимы для изменения форматирования переменных даты/времени и неправильного использования (отказ от предварительной обработки в случае варианта № 1 и ошибочное использование time.Time вместо пользовательского типа в случае варианта № 2). ).
По этой причине изменение форматированного вывода из gorm было бы для меня предпочтительным подходом, если это возможно.
Самым быстрым решением было отформатировать данные/значение при чтении из БД, как это было предложено @Deltics.
При запросе данных из БД с помощью DATE_FORMAT() я форматирую данные в формате, требуемом go/json
DATE_FORMAT(actual_data, '%Y-%m-%dT%TZ')
Вы должны объявить свой собственный тип времени с помощью пользовательского маршаллера, если ваш ввод не соответствует RFC-3339. Этот пост может вам помочь: romangaranin.net/posts/2021-02-19-json-time-and-golang