背景:楼上需求方又双叒来提需求来来,这次是想要判断两个时间的天数差,
if 天数差 > xx and 天数差 < yy:
。。。。
在python中,我们有很多比如time包,datetime包中的方法可以帮助我们完成时间差的计算,比如
from datetime import date, datetime
def date_diff(date1, date2=None, format="%Y-%m-%d %H:%M:%S"):
"""
计算日期差,传入默认都是str的
"""
date1 = datetime.strptime(date1, format).date() if isinstance(date1, str) else date1.date()
if date2:
date2 = datetime.strptime(date2, format).date()
else:
date2 = date.today()
return abs(date2 - date1).days
def month_delta(start_date, end_date=datetime.now()):
"""
计算月份之差
返回 end_date - start_date 的差值
:param start_date:
:param end_date:
:return: month_delta int
"""
return (end_date.year - start_date.year) * 12 + end_date.month - start_date.month
但是在golang中的time包,并不会像python中那样“友好的”来计算时间天数差。
在前不久的项目中,本人就因为对time包对用法理解不到位,导致踩了很多坑。
一开始需求方大大们要求算一个日期差,单纯的我以为日期差就是直接取两个时间的Day()属性然后做减法:
time1 := "2020-03-01 10:10:10"
t2, _ := time.Parse("2006-01-02 15:04:05", time1)
dt := time.Now().Day() - t2.Day()
没想到测试竟然没发现bug(主要是我和测试都没用到跨月的case),前几天在review的过程中发现来这个问题,赶紧fix掉:
time1 := "2020-03-01 10:10:10"
loc, _ := time.LoadLocation("Local") //获取时区
tmp, _ := time.ParseInLocation("2006-01-02 15:04:05", time1, loc)
timestamp := tmp.Unix() //转化为时间戳 类型是int64
dt := (time.Now().Unix() - timestamp) / 86400
使用time.LoadLocation方法来获取本地的时区,消除由于时区不同而导致的时间差问题,当然这个方法计算的是两个时间差所除以86400秒数后所得的天数,并不是原需求中的两个日期的差(例如:“2020-02-02 12:00:00” 与“2020-02-03 11:00:00” 的日期天数差为1)
下面用了一个字符串解析的方法来做date_diff函数(没想到更好的方法,欢迎大佬指教一二)
timestr := "2020-05-01 12:12:12"
t1 := strings.Split(timestr, " ")
s1 := t1[0] + " 00:00:00"
t2, _ := time.Parse("2006-01-02 15:04:05", s1)
t3, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 00:00:00"))
dt := t3.Sub(t2).Hours() / 24