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

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

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

问题

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

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

{{"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":[]}

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

createdAt, err := time.Parse(time.RFC3339, blog.CreatedAt.String())
if err != nil {
    return nil, err
}
updatedAt, err := time.Parse(time.RFC3339, blog.UpdatedAt.String())
if err != nil {
    return nil, err
}

tempBlog := &api.Blog{
	Id: blog.ID,
	CreatedAt: timestamppb.New(createdAt),
    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:

{{"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.

createdAt, err := time.Parse(time.RFC3339, blog.CreatedAt.String())
if err != nil {
    return nil, err
}
updatedAt, err := time.Parse(time.RFC3339, blog.UpdatedAt.String())
if err != nil {
    return nil, err
}

tempBlog := &api.Blog{
	Id: blog.ID,
	CreatedAt: timestamppb.New(createdAt),
    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'函数会给你所需的结果。

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

结果为:

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

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

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

这将给出以下结果:

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

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

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

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

result

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

And if you need it back in RFC3339 to export use

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

that will give you as a result

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

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

答案3

得分: 1

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

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

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

MongoDB以以下方式存储时间:

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

源代码在这里: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().

package date_test

import (
	"context"
	"github.com/stretchr/testify/require"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"os"
	"testing"
	"time"
)

type Something struct {
	Name       string    `json:"name" bson:"name"`
	CreateTime time.Time `json:"createTime" bson:"createTime"`
}

func TestDate(t *testing.T) {
	raw := Something{Name: "demo", CreateTime: time.Now()}
	t.Logf("raw: %v", raw)
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("URI")))
	require.NoError(t, err)
	collection := client.Database("test").Collection("demo")
	_, err = collection.InsertOne(ctx, raw)
	require.NoError(t, err)
	var res Something
	err = collection.FindOne(ctx, bson.D{{"name", raw.Name}}).Decode(&res)
	require.NoError(t, err)
	t.Logf("res: %v", res)
	t.Logf("local time: %v", res.CreateTime.Local())
}

Run the test code it will print something like this

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

the mongo store the time like this

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

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:

确定