engine
.
TZLocation
,
_
=
time
.
LoadLocation
(
"Asia/Shanghai"
)
engine
.
DatabaseTZ
,
_
=
time
.
LoadLocation
(
"Asia/Shanghai"
)
err
=
engine
.
Sync2
(
new
(
Tag
))
if
err
!=
nil
{
panic
(
err
)
func
main
()
{
tag
:=
new
(
Tag
)
tag
.
Name
=
time
.
Now
().
String
()
if
_
,
err
:=
engine
.
Insert
(
tag
);
err
!=
nil
{
panic
(
err
)
var
result
List
err
:=
engine
.
Find
(
&
result
)
if
err
!=
nil
{
panic
(
err
)
fmt
.
Println
(
"通过结构体查询"
,
result
[
0
].
CreatedAt
)
j
,
_
:=
json
.
Marshal
(
result
)
fmt
.
Println
(
"json格式化结构体后"
,
string
(
j
))
m
,
_
:=
engine
.
Query
(
"select * from tag"
)
fmt
.
Println
(
"sql语句查询"
,
string
(
m
[
0
][
"created_at"
]))
if
engine
.
Close
()
==
nil
{
_
=
os
.
Remove
(
"test.db"
)
时间的入库:
xorm在插入时间的时候会进行格式化,此时xorm会丢失掉时区相关的信息,因为格式化的格式是:
2006-01-02 15:04:05
,不包含时区。
时间的出库:
当sqlite3拿到数据的时候会进行解析,因为xorm格式化的时候丢失了时区,此时sqlite3是按utc时区进行解析,然后sqlite3再根据打开时候的配置
_loc
的时区进行转换,这个时候时间就会产生了异常,然后xorm拿到的时间就是异常的,此时xorm也会判断sqlite3吐出的时区是否和配置的
engine.DatabaseTZ
相等,如果不相等也会进行转换。
xorm的时间入库处理代码
sqlite3的时间出库处理代码
xorm的时间出库处理代码
type Tag struct {
ID int `xorm:"not null pk autoincr INTEGER"`
CreatedAt time.Time `xorm:"DateTime created"`
UpdatedAt time.Time `xorm:"DateTime updated"`
Name string `xorm:"unique TEXT"`
type List []*Tag
func init() {
var err error
//sqlite3的时区设置为上海
engine, err = xorm.NewEngine("sqlite3", "test.db?_loc=Asia/Shanghai")
if err != nil {
panic(err)
//本程序时区与数据库时区都设置为上海
engine.TZLocation,_ = time.LoadLocation("Asia/Shanghai")
engine.DatabaseTZ,_ = time.LoadLocation("Asia/Shanghai")
err = engine.Sync2(new(Tag))
if err != nil {
panic(err)
func main() {
tag := new(Tag)
tag.Name = time.Now().String()
if _, err := engine.Insert(tag); err != nil {
panic(err)
var result List
err := engine.Find(&result)
if err != nil {
panic(err)
fmt.Println("通过结构体查询" ,result[0].CreatedAt)
j, _ := json.Marshal(result)
fmt.Println("json格式化结构体后", string(j))
m, _ := engine.Query("select * from tag")
fmt.Println("sql语句查询", string(m[0]["created_at"]))
if engine.Close() == nil {
_ = os.Remove("test.db")
#### 问题分析
**时间的入库:** xorm在插入时间的时候会进行格式化,此时xorm会丢失掉时区相关的信息,因为格式化的格式是:`2006-01-02 15:04:05`,不包含时区。
**时间的出库:** 当sqlite3拿到数据的时候会进行解析,因为xorm格式化的时候丢失了时区,此时sqlite3是按utc时区进行解析,然后sqlite3再根据打开时候的配置`_loc`的时区进行转换,这个时候时间就会产生了异常,然后xorm拿到的时间就是异常的,此时xorm也会判断sqlite3吐出的时区是否和配置的`engine.DatabaseTZ`相等,如果不相等也会进行转换。
1. [xorm的时间入库处理代码](https://gitea.com/xorm/xorm/src/branch/master/dialects/time.go#L21)
2. [sqlite3的时间出库处理代码](https://github.com/mattn/go-sqlite3/blob/master/sqlite3.go#L2093)
3. [xorm的时间出库处理代码](https://gitea.com/xorm/xorm/src/branch/master/session.go#L651)
Which version are you using? Once you set
engine.DatabaseTZ
, the previous data on database will not be changed with the new time one.
版本:xorm.io/xorm v0.8.2
上面的例子,可以复现我的问题,数据每次都是新的,因为
os.Remove("test.db")
sqlite3 has a default DatabaseTZ as UTC, but since you override it. I think this should not an issue.
Could you help to confirm this is still a problem?