Parsing a date from a mongoDB with golang time.Now()

huangapple go评论124阅读模式
英文:

Parsing a date from a mongoDB with golang time.Now()

问题

我正在使用Go通过time.Now()创建一个日期,并将其存储在MongoDB中没有问题。日期的格式看起来像是2023-02-28T20:10:46.140+00:00

然而,当我尝试检索它时,我收到了一个错误消息,内容如下:

  1. {{"code":2, "message":"parsing time \"2023-02-28 20:10:46.14 +0000 UTC\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \" 20:10:46.14 +0000 UTC\" as \"T\"", "details":[]}

这个错误来自以下代码段。

  1. createdAt, err := time.Parse(time.RFC3339, blog.CreatedAt.String())
  2. if err != nil {
  3. return nil, err
  4. }
  5. updatedAt, err := time.Parse(time.RFC3339, blog.UpdatedAt.String())
  6. if err != nil {
  7. return nil, err
  8. }
  9. tempBlog := &api.Blog{
  10. Id: blog.ID,
  11. CreatedAt: timestamppb.New(createdAt),
  12. UpdatedAt: timestamppb.New(updatedAt),

我在这里找到了一些有用的文档链接1链接2,并手动将解析后的时间添加到Mongo中,但仍然遇到了这个问题。

我尝试了所有的时间格式,但结果都是无法解析的不同错误。

有什么建议吗?

英文:

I am creating a date using Go via time.Now() and it store it in the mongoDB with no issue. The date looks like 2023-02-28T20:10:46.140+00:00.

However when I try to retrieve it I get an error that reads:

  1. {{"code":2, "message":"parsing time \"2023-02-28 20:10:46.14 +0000 UTC\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \" 20:10:46.14 +0000 UTC\" as \"T\"", "details":[]}

It is coming from this piece of code.

  1. createdAt, err := time.Parse(time.RFC3339, blog.CreatedAt.String())
  2. if err != nil {
  3. return nil, err
  4. }
  5. updatedAt, err := time.Parse(time.RFC3339, blog.UpdatedAt.String())
  6. if err != nil {
  7. return nil, err
  8. }
  9. tempBlog := &api.Blog{
  10. Id: blog.ID,
  11. CreatedAt: timestamppb.New(createdAt),
  12. UpdatedAt: timestamppb.New(updatedAt),

I found some useful documentation here and here and added the times parsed into Mongo manually, but I still run into this issue.

I have tried all of the time formats but it just results in a different error that is not able to parse.

Advice?

答案1

得分: 1

你正在使用的time.parse的布局是time.RFC33392006-01-02T15:04:05Z07:00

当我从Elastic解析时间时,我遇到了类似的消息,但是通过删除尾部的07:00,我成功解决了这个问题。尝试使用自定义布局2006-01-02T15:04:05Z,而不是RFC3339。

英文:

The layout you are using for time.parse is time.RFC3339 or 2006-01-02T15:04:05Z07:00.

I had a similar message when parsing time from Elastic, but was able to resolve it by removing the trailing 07:00. Try using a custom layout 2006-01-02T15:04:05Z instead of RFC3339.

答案2

得分: 1

你的输入格式(2023-02-28 20:10:46.14 +0000 UTC),如你的错误信息所示,无法被time.parse函数识别,因为它不是RFC3339格式,你在函数中调用了它。
我不常使用内置函数,但是这个'format'函数会给你所需的结果。

  1. inputs := "2023-02-28 20:10:46.14 +0000 UTC"
  2. extime, _ := time.Parse("2006-01-02 15:04:05 -0700 MST", inputs)
  3. fmt.Println("Time : ", extime)

结果为:

  1. Time : 2023-02-28 20:10:46.14 +0000 UTC

如果你需要将其转换为RFC3339格式进行导出,可以使用以下代码:

  1. fmt.Println("RFC3339 : ", extime.Format("2006-01-02T15:04:05Z07:00"))

这将给出以下结果:

  1. RFC3339 : 2023-02-28T20:10:46Z

请注意,在UTC时间(Zulu时间)中,RFC3339不要求提供时间修正,只需使用Z。如果你的输入中有-0700 MST而不是+0000 UTC,结果将为:

  1. RFC3339 : 2023-02-28T20:10:46-07:00
英文:

your input format (2023-02-28 20:10:46.14 +0000 UTC), as shown in your error message, can't be recognised by the time.parse function as it's not a RFC3339 format you called in the function.
I don't use much built in function but this 'format' function will give you what you need

  1. inputs := "2023-02-28 20:10:46.14 +0000 UTC"
  2. extime, _ := time.Parse("2006-01-02 15:04:05 -0700 MST", inputs)
  3. fmt.Println("Time : ", extime)

result

  1. Time : 2023-02-28 20:10:46.14 +0000 UTC

And if you need it back in RFC3339 to export use

  1. fmt.Println("RFC3339 : ", extime.Format("2006-01-02T15:04:05Z07:00"))

that will give you as a result

  1. RFC3339 : 2023-02-28T20:10:46Z

Note that in UTC time (Zulu time) the RFC3339 don't ask to give the time modification just Z. If you had for example -0700 MST instead of +0000 UTC the result would have been

  1. RFC3339 : 2023-02-28T20:10:46-07:00

答案3

得分: 1

如果你将time.Time存储在MongoDB中,MongoDB会自动为你检索时间。检索到的时间是以UTC格式显示的,如果你想要转换为本地时区,可以使用time.Local()

运行测试代码,会打印出类似以下的内容:

  1. $ URI="mongodb://127.0.0.1:27017/" go test -v ./date_test.go
  2. === RUN TestDate
  3. date_test.go:21: raw: {demo 2023-03-07 10:26:22.433473 +0800 CST m=+0.009080292}
  4. date_test.go:32: res: {demo 2023-03-07 02:26:22.433 +0000 UTC}
  5. date_test.go:33: local time: 2023-03-07 10:26:22.433 +0800 CST
  6. --- PASS: TestDate (0.01s)
  7. PASS
  8. ok command-line-arguments 0.912s

MongoDB以以下方式存储时间:

  1. > db.demo.find().pretty()
  2. {
  3. "_id" : ObjectId("6406a0ce4cfff0411ca8d98b"),
  4. "name" : "demo",
  5. "createTime" : ISODate("2023-03-07T02:26:22.433Z")
  6. }

源代码在这里:https://gist.github.com/alex-x-crypto/14c15d4921f1ece2962302cce87c97a8

英文:

If you store time.Time MongoDB will auto retrieve it for you. The retrieved time is on UTC, if you want change to your local timezone, use time.Local().

  1. package date_test
  2. import (
  3. "context"
  4. "github.com/stretchr/testify/require"
  5. "go.mongodb.org/mongo-driver/bson"
  6. "go.mongodb.org/mongo-driver/mongo"
  7. "go.mongodb.org/mongo-driver/mongo/options"
  8. "os"
  9. "testing"
  10. "time"
  11. )
  12. type Something struct {
  13. Name string `json:"name" bson:"name"`
  14. CreateTime time.Time `json:"createTime" bson:"createTime"`
  15. }
  16. func TestDate(t *testing.T) {
  17. raw := Something{Name: "demo", CreateTime: time.Now()}
  18. t.Logf("raw: %v", raw)
  19. ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
  20. defer cancel()
  21. client, err := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("URI")))
  22. require.NoError(t, err)
  23. collection := client.Database("test").Collection("demo")
  24. _, err = collection.InsertOne(ctx, raw)
  25. require.NoError(t, err)
  26. var res Something
  27. err = collection.FindOne(ctx, bson.D{{"name", raw.Name}}).Decode(&res)
  28. require.NoError(t, err)
  29. t.Logf("res: %v", res)
  30. t.Logf("local time: %v", res.CreateTime.Local())
  31. }

Run the test code it will print something like this

  1. $ URI="mongodb://127.0.0.1:27017/" go test -v ./date_test.go
  2. === RUN TestDate
  3. date_test.go:21: raw: {demo 2023-03-07 10:26:22.433473 +0800 CST m=+0.009080292}
  4. date_test.go:32: res: {demo 2023-03-07 02:26:22.433 +0000 UTC}
  5. date_test.go:33: local time: 2023-03-07 10:26:22.433 +0800 CST
  6. --- PASS: TestDate (0.01s)
  7. PASS
  8. ok command-line-arguments 0.912s

the mongo store the time like this

  1. > db.demo.find().pretty()
  2. {
  3. "_id" : ObjectId("6406a0ce4cfff0411ca8d98b"),
  4. "name" : "demo",
  5. "createTime" : ISODate("2023-03-07T02:26:22.433Z")
  6. }

source code is here https://gist.github.com/alex-x-crypto/14c15d4921f1ece2962302cce87c97a8

huangapple
  • 本文由 发表于 2023年3月1日 04:18:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75596904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定