Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gtime.String() lost timezone #3188

Closed
qinyuguang opened this issue Dec 4, 2023 · 6 comments
Closed

gtime.String() lost timezone #3188

qinyuguang opened this issue Dec 4, 2023 · 6 comments

Comments

@qinyuguang
Copy link
Contributor

qinyuguang commented Dec 4, 2023

1. What version of Go and system type/arch are you using?

go version go1.21.3 darwin/arm64

2. What version of GoFrame are you using?

gf v2.5.7

3. Can this issue be re-produced with the latest release?

yes

4. What did you do?

marshal a map which contains gtime.Time, the result lost timezone.

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
)

func main() {
	time := gtime.NewFromStr("2023-12-01T00:00:00.000000Z")

	msg := g.Map{
		"time1": time,
		"time2": time.Local(),
	}

	fmt.Print(gjson.New(msg).MustToJsonIndentString())
}

5. What did you expect to see?

with local timezone

{
        "time1": "2023-12-01 08:00:00",
        "time2": "2023-12-01 08:00:00"
}

or same result as encoding/json marshal

{
        "time1": "2023-12-01T00:00:00.000000Z",
        "time2": "2023-12-01T00:00:00.000000Z"
}

6. What did you see instead?

{
        "time1": "2023-12-01 00:00:00",
        "time2": "2023-12-01 08:00:00"
}

Since gtime.String() loses timezone, can it be formatted to the local timezone by default?

https://github.com/gogf/gf/blob/master/os/gtime/gtime_time.go#L265

return t.wrapper.String()

change to:

return t.Local().wrapper.String()

@gqcn

@oldme-git
Copy link
Member

This's not problem. NewFromStr defaults to UTC. time.Local has set +08:00

@qinyuguang
Copy link
Contributor Author

for example:

I receive a json string like this:

{"time": "2023-12-01T00:00:00.000000Z"}

convert it to struct:

type A struct {
    Time *gtime.Time `json:"time"`
}

then marshal the struct to a new json string:

{"time": "2023-12-01 00:00:00"}

@gqcn
Copy link
Member

gqcn commented Dec 5, 2023

@qinyuguang gtime.Time does not convert the time with time.Local unless you manually call .Local(), which is the same logic as time.Time of stdlib.

@gqcn gqcn added the question label Dec 5, 2023
@qinyuguang
Copy link
Contributor Author

code

package main

import (
	"fmt"
	"time"

	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/gconv"
)

type T1 struct {
	Time1 *gtime.Time `json:"time1"`
	Time2 *gtime.Time `json:"time2"`
}

type T2 struct {
	Time1 *time.Time `json:"time1"`
	Time2 *time.Time `json:"time2"`
}

func main() {
	str := `{"time1": "2023-12-01T00:00:00.000000Z", "time2": "2023-12-01T00:00:00.000000+08:00"}`

	var (
		t1 *T1
		t2 *T2
	)

	_ = gconv.Struct(str, &t1)
	_ = gconv.Struct(str, &t2)

	s1 := gjson.New(t1).MustToJsonIndentString()
	s2 := gjson.New(t2).MustToJsonIndentString()

	fmt.Println(s1)
	fmt.Println(s2)
}

output

{
        "time1": "2023-12-01 00:00:00",
        "time2": "2023-12-01 00:00:00"
}
{
        "time1": "2023-12-01T00:00:00Z",
        "time2": "2023-12-01T00:00:00+08:00"
}

Is this result expected?

time.Time retains the timezone, but gtime.Time loses the timezone.
If use gtime.Time, need to additionally know the potential meaning of each time field.

What I mean is that instead of letting people know the timezone of each field, after conversion, all time fields become the current timezone set by gtime.

@qinyuguang
Copy link
Contributor Author

anything new?

@github-actions github-actions bot removed the inactive label Dec 20, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jan 26, 2024
@xiaobai1993
Copy link

I find the gdb debug mode can output the raw sql, will this problem cause the output raw sql is not the sql that the database really execute? for example when use postgre database,the field type is timestamp with time zone , I did find the debug mode sql seems not the real query sql, this makes me confused。

yesterday,our sandbox database change the timezone from Asia/Shanghai to UTF8, then I find some test case can't pass,
finally,I find this fix:1a271ce6270b31118e1cf87c352496e7a6429250, I think this may
be bug(the time param to build the sql is not expected:loss time zone info) that have fixed,so I upgrade my gf version from 2.0.3 to 2.6.2. but I find some of unit test can not pass that can pass in old version. so I checkout two branch and open the debug mode, want to find what happened, but the two branch debug sql,both of them are like the following:

SELECT * FROM table WHERE ((updated_at < '2024-02-02 14:46:58' or (updated_at = '2024-02-02 14:46:58' and id < 498831613225467905 )) AND ("subsidy_id"=498831613224812545)) AND "deleted_at" IS NULL ORDER BY "updated_at" desc,"id" desc LIMIT 2。

but the fact is 2.0.3 can pass,2.6.2 can’t。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants