英文:
Time always 0 in a go program
问题
我正在尝试从Bitfinex API获取交易并将其打印在屏幕上。除了时间之外,一切都正常工作。
我想知道为什么在这个例子中它们总是打印为0001-01-01 00:00:00...
在UnmarshalJSON中,"t"包含我需要的时间。只是似乎无法与Trade结构保持一致。
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"
)
type Trade struct {
	Tid       int
	Timestamp myTime
}
type myTime time.Time
func (t myTime) String() string {
	when := time.Time(t)
	return when.Format("2006-01-02 15:04:05")
}
func (t myTime) UnmarshalJSON(b []byte) error {
	ts, err := strconv.Atoi(string(b))
	if err != nil {
		return err
	}
	t = myTime(time.Unix(int64(ts), 0))
	return nil
}
func main() {
	trades, _ := GetTrades()
	for _, trade := range trades {
		fmt.Printf("%d - %s\n", trade.Tid, trade.Timestamp)
	}
}
func GetTrades() (trades []Trade, err error) {
	r, err := http.Get("https://api.bitfinex.com/v1/trades/BTCUSD")
	defer r.Body.Close()
	body, _ := ioutil.ReadAll(r.Body)
	json.Unmarshal(body, &trades)
	return
}
以上是你提供的代码。
英文:
I am trying here to get trades from Bitfinex API and print them on the screen. Everything works fine, except for times.
I wonder why they always prints as 0001-01-01 00:00:00 in this example...
In UnmarshalJSON, "t" contains the time I need. It just doesn't seem to stick to the Trade structure.
package main
import (
        "encoding/json"
        "fmt"
        "io/ioutil"
        "net/http"
        "strconv"
        "time"
)
type Trade struct {
        Tid       int
        Timestamp myTime
}
type myTime time.Time
func (t myTime) String() string {
        when := time.Time(t)
        return when.Format("2006-01-02 15:04:05")
}
func (t myTime) UnmarshalJSON(b []byte) error {
        ts, err := strconv.Atoi(string(b))
        if err != nil {
                return err
        }
        t = myTime(time.Unix(int64(ts), 0))
        return nil
}
func main() {
        trades, _ := GetTrades()
        for _, trade := range trades {
                fmt.Printf("%d - %s\n", trade.Tid, trade.Timestamp)
        }
}
func GetTrades() (trades []Trade, err error) {
        r, err := http.Get("https://api.bitfinex.com/v1/trades/BTCUSD")
        defer r.Body.Close()
        body, _ := ioutil.ReadAll(r.Body)
        json.Unmarshal(body, &trades)
        return
}
答案1
得分: 5
你可以在指针接收器上进行解组,否则你只是在复制不相关的数据:
func (t *myTime) UnmarshalJSON(b []byte) error {
    //  ^^^^^^^ 这里
    ts, err := strconv.Atoi(string(b))
    if err != nil {
        return err
    }
    *t = myTime(time.Unix(int64(ts), 0))
 // ^^ 这里也是
    return nil
}
我不确定在指针接收器中重新分配数据的做法在安全性和惯用性上如何,有人可以澄清吗?
(这个方法是可行的,但不确定是否符合“最佳实践”)
英文:
You can unmarshal on a pointer receiver .. otherwise you're just copying unrelated data around:
func (t *myTime) UnmarshalJSON(b []byte) error {
    //  ^^^^^^^ this
    ts, err := strconv.Atoi(string(b))
    if err != nil {
            return err
    }
    *t = myTime(time.Unix(int64(ts), 0))
 // ^^ this too
    return nil
}
I'm not sure how "safe"/"idiomatic" this is to re-assign data in a pointer receiver.. can someone clarify?
(this works btw.. not sure if its "best practice")
答案2
得分: 1
你可以在UnmarshalJSON中不能给一个值赋值,你必须使用指针或结构体,一种方法是:
type MyTime struct {
    time.Time
}
func (t MyTime) String() string {
    when := time.Time(t.Time)
    return when.Format("2006-01-02 15:04:05")
}
func (t *MyTime) UnmarshalJSON(b []byte) error {
    ts, err := strconv.Atoi(string(b))
    if err != nil {
        return err
    }
    t.Time = time.Unix(int64(ts), 0)
    return nil
}
英文:
You can't assign in UnmarshalJSON to a value, you have to use a pointer or a struct, one approach is:
type MyTime struct {
	time.Time
}
func (t MyTime) String() string {
	when := time.Time(t.Time)
	return when.Format("2006-01-02 15:04:05")
}
func (t *MyTime) UnmarshalJSON(b []byte) error {
	ts, err := strconv.Atoi(string(b))
	if err != nil {
		return err
	}
	t.Time = time.Unix(int64(ts), 0)
	return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论