Формат даты изменяется при использовании его через пользовательские типы

Я очень новичок в golang и все еще борюсь со многими вещами.

При реализации пользовательского типа, подобного этому type Date time.Time, определяющего метод для маршалирования/демаршалирования дат, которые поступают в формате "2006-01-02" (из файла JSON и из запроса API POST), окончательный способ хранения дат в структуре:

{wall:0 ext:63776764800 loc:<nil>}

Может ли кто-нибудь помочь мне понять, почему этот формат (вместо обычного time.Time), поскольку пользовательский тип Date пишется с большой буквы, следовательно, экспортируется?

Вот реализация (ссылка на игровую площадку под кодом):

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"
)

const sample = `{
    "ID": "1",
    "ticker": "S30J2",
    "issueDate": "2022-01-31",
    "maturity": "2023-06-30",
    "coupon": 0,
    "cashFlow": [
        {   "date": "2022-06-30",
            "rate": 0,
            "amortization": 1,
            "residual": 0,
            "amount": 50},
            {
            "date": "2023-06-30",
            "rate": 0,
            "amortization": 1,
            "residual": 0,
            "amount": 50}
    ]
}`

type Date time.Time

func (d Date) MarshalJSON() ([]byte, error) {
    return []byte(time.Time(d).Format("2006-1-2")), nil
}

func (d *Date) UnmarshalJSON(b []byte) error {
    // Disregard leading and trailing "
    t, err := time.Parse("2006-1-2", string(b[1:len(b)-2]))
    if err != nil {
        return err
    }
    *d = Date(t)
    return nil
}

type Flujo struct {
    Date     Date
    Rate     float64
    Amort    float64
    Residual float64
    Amount   float64
}
type Bond struct {
    ID        string
    Ticker    string
    IssueDate Date
    Maturity  Date
    Coupon    float64
    Cashflow  []Flujo
}

func main() {
    var b Bond
    if err := json.Unmarshal([]byte(sample), &b); err != nil {
        log.Fatalf("%s", err)
    }
    fmt.Printf("%+v\n", b.IssueDate)
    // I need to wrap it via Format.
    fmt.Println("Fecha: ", time.Time(b.IssueDate).Format("2006-01-02"))

}

Вот рабочий пример: https://go.dev/play/p/YddzXA9PQdP

Спасибо за помощь и понимание.

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
0
28
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Тип Date — это новый именованный тип, отличный от time.Time, и у него нет методов, определенных для time.Time. Методы маршала/демаршала работают нормально, но семейство функций fmt.Print использует интерфейс Stringer, если он существует. Таким образом, если вы объявите:

func (d Date) String() string {
    x, _ := d.MarshalJSON()
    return string(x)
}

Он будет печатать правильно.

Спасибо Бурак! Я упустил из виду, что Date должен быть снабжен правильными методами для печати (т.е. String()) как time.Time

Juan M 21.03.2022 18:11

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