添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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 相等,如果不相等也会进行转换。

  • 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")

    > 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?

    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?