Home > Enterprise >  Format of date changes when using it via custom types
Format of date changes when using it via custom types

Time:03-22

I'm very new to golang and still struggling with many things.

When implementing custom type like this type Date time.Time, an defining a method to marshal/unmarshal dates that come in "2006-01-02" format (from a JSON file and from a POST API request), the final way in which dates are stored in the struct is:

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

Can someone help me understand why that format (instead of regular time.Time) since the custom type Date is capitalized, hence exported?

Here an implementation (link to playground below the code):

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"))

}

Here the working example: https://go.dev/play/p/YddzXA9PQdP

Thanks for the help and understanding.

CodePudding user response:

The type Date is a new named type distinct from time.Time, and it does not have the methods defined for time.Time. The marshal/unmarshal methods work just fine, but fmt.Print family of function use the Stringer interface if one exists. Thus if you declare:

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

It will print correctly.

  • Related