在生成的时候发现数据库的时间慢了8个小时,后来发现是需要在连接数据库的时候加上参数&loc=local
func init(){
driverName := viper.GetString("datasource.driverName")
host := viper.GetString("datasource.host")
port := viper.GetString("datasource.port")
database := viper.GetString("datasource.database")
username := viper.GetString("datasource.username")
password := viper.GetString("datasource.password")
charset := viper.GetString("datasource.charset")
args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local", //loc=local不能忘记
username,
password,
host,
port,
database,
charset)
db, err := gorm.Open(driverName, args)
if err != nil {
panic("failed to connect database err: " + err.Error())
}
db.AutoMigrate(&defs.Users{})
db.AutoMigrate(&defs.Video_Info{})
db.AutoMigrate(&defs.Comments{})
db.AutoMigrate(&defs.Sessions{})
dbConn=db
}
问题2 go内置的time一些问题
使用time.Parse()
解析字符串生成的时间的时区是UTC,而你调用time.Now()
则是CST,这导致你数据库中查时间段的数据会出错,如下代码
func TestListComments(t *testing.T) {
vid:="123"
layout:="Jan 02 2006, 15:04:05"
from,_:=time.Parse(layout,"Dec 14 2021, 20:18:15")//不加载时区
fromUnix:=from.Unix()
fmt.Println(from)
fmt.Println(fromUnix)
to:=time.Now()
toUnix:=to.Unix()
fmt.Println(to)
fmt.Println(toUnix)
comments, err := ListComments(vid, fromUnix, toUnix)
if err!=nil{
t.Errorf("Error of list comments:%v",err)
}
for _,val:=range comments{
fmt.Printf("%#v",val)
}
}
输出有误
2021-12-14 20:18:15 +0000 UTC
1639513095 //开始时间反而大于 结束时间,因为时区不对
2021-12-14 21:22:25.3100649 +0800 CST m=+0.032457601
1639488145
解析字符串并加载时区之后,时区一致
func TestListComments(t *testing.T) {
vid:="123"
layout:="Jan 02 2006, 15:04:05"
// 加载时区
loc, err := time.LoadLocation("Asia/Shanghai") //一定要这个否则会弄错的
from,_:=time.ParseInLocation(layout,"Dec 14 2021, 20:18:15",loc)
fromUnix:=from.Unix()
fmt.Println(from)
fmt.Println(fromUnix)
to:=time.Now()
toUnix:=to.Unix()
fmt.Println(to)
fmt.Println(toUnix)
comments, err := ListComments(vid, fromUnix, toUnix)
if err!=nil{
t.Errorf("Error of list comments:%v",err)
}
for _,val:=range comments{
fmt.Printf("%#v",val)
}
}
输出
2021-12-14 20:18:15 +0800 CST
1639484295
2021-12-14 21:20:16.129897 +0800 CST m=+0.088633101
1639488016
.....一些comment数据
问题3 mysql中的时间问题
我用gorm查询某个时间段的评论代码如下,可以看到我是以from和to 两个int64 类型,来作为查询条件,这是为了对应go中的unix时间戳也是int64
func ListComments(vid string ,from,to int64) ([]*defs.CommentWithName,error) {
lock.RLock()
defer lock.RUnlock()
var res []*defs.CommentWithName
dbConn.Debug().Raw("select comments.id,users.username,comments.content FROM comments "+
"INNER JOIN users on comments.author_id=users.id where comments.video_id=? AND comments.created_at > FROM_UNIXTIME(?) AND "+
"comments.created_at <= FROM_UNIXTIME(?)", vid, from, to).Scan(&res)
return res,nil
}
但是他在Mysql内部执行的时候出了一些问题,什么问题呢,也是时区问题。
关键在于FROM_UNIXTIME(?)
这个函数,他这个函数是将unix时间戳转为正常时间,这个正常时间是和时区有关的,你相同的unix时间戳转为不同时区的正常时间,它是不一样的。
所导致的问题
这会导致一个什么问题,就是你在插入评论的时候,插入的created_at这个字段的值是你的时区时间,但是你在查找的时候,mysql调用FROM_UNIXTIME(?)
这个函数转化的时间又是另外时区的时间,那么你查询的时候就会出问题。
基础命令熟悉
在实验之前,先准备一下基础的命令
FROM_UNIXTIME(unix_timestamp,format)
返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。
SELECT FROM_UNIXTIME(1234567890, '%Y-%m-%d %H:%i:%S')
正常时间格式转换成unix时间戳
select unix_timestamp(current_date);
show variables like "%time_zone%";
查看时区
±-----------------±-------+
| Variable_name | Value |
±-----------------±-------+
| system_time_zone | CST |
| time_zone | SYSTEM |
±-----------------±-------+
2 rows in set (0.00 sec)
#time_zone说明mysql使用system的时区,system_time_zone说明system使用CST时区
修改时区
set global time_zone = '+8:00';
##修改mysql全局时区为北京时间,即我们所在的东8区
set time_zone = '+8:00';
##临时修改,只用于当前会话
flush privileges;
#立即生效
然后当你设置不同的时区的时候,把unix时间戳转为正常时间就会不一样
情况1 当时区为+8.00
system_time_zone
time_zone+08:00
执行
select from_unixtime(1639484295,'%Y-%m-%d %H:%i:%S')
得到2021-12-14 20:18:15
情况2 当时区为+0.00
system_time_zone
time_zone+00:00
执行
select from_unixtime(1639484295,'%Y-%m-%d %H:%i:%S')
得到2021-12-14 12:18:15
差了8个小时
因此即然时间不对,那么你去查找某一时间段的内容,当然也会找不出。
所以在使用这三个内容的时候需要注意时间问题
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)