英文:
Format of date changes when using it via custom types
问题
我对golang非常陌生,仍然在许多方面苦苦挣扎。
当实现自定义类型时,例如type Date time.Time
,并定义一个方法来编组/解组以"2006-01-02"
格式出现的日期(来自JSON文件和POST API请求),结构体中日期的最终存储方式是:
{wall:0 ext:63776764800 loc:<nil>}
有人可以帮助我理解为什么会出现这种格式(而不是常规的time.Time
),因为自定义类型Date
是大写的,因此是公开的吗?
这里是一个实现(代码下方有指向playground的链接):
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
感谢帮助和理解。
英文:
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.
答案1
得分: 2
类型Date
是一个与time.Time
不同的新命名类型,并且它没有为time.Time
定义的方法。marshal/unmarshal方法可以正常工作,但是fmt.Print
系列函数会使用Stringer
接口(如果存在)。因此,如果你声明如下:
func (d Date) String() string {
x, _ := d.MarshalJSON()
return string(x)
}
它将正确打印输出。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论