我试图在Go中的两个日期之间获得天数,但是当我得到时间(小时)的差异然后除以每天的时间量时,我有一个问题。
问题:如果日期不同(5月7日和5月8日)但是从那时起的时间低于24小时,我的代码计算为没有天数。
我想要的是什么:计算两者之间的实际日期。
// Days
firstDay := firstDate.Unix()
lastDay := lastDate.Unix()
fmt.Println("firstDay: ", firstDay)
fmt.Println("lastDay: ", lastDay)
if firstDay > lastDay {
fmt.Println("IS TO SMALL")
return
}
// businessDays =
businessDays := (lastDay - firstDay) / 86400
fmt.Println("businessDays: ", businessDays)
非常感谢。
答案 0 :(得分:3)
源代码:
package main
import (
"fmt"
"math"
"time"
)
func main() {
d1, err := time.Parse("200601021504", "201801020001")
if err != nil {
panic(err)
}
d2, err := time.Parse("200601021504", "201801020002")
if err != nil {
panic(err)
}
newD1 := d1.Truncate(time.Hour * 24)
newD2 := d2.Truncate(time.Hour * 24)
fmt.Printf("days: %v\n", math.Ceil(newD2.Sub(newD1).Hours()/24))
}
答案 1 :(得分:1)
由于性能现在是一个问题(我怀疑),我用一些方法写了一些基准:
func TrimToDate(t time.Time) time.Time {
y, m, d := t.Date()
return time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
}
func CountTrim(t1, t2 time.Time) int {
return int((t2.Unix() - TrimToDate(t1.Unix())) / 86400)
}
func CountUnixAdd(t1, t2 time.Time) int {
Days := (t1.Unix() - t2.Unix()) / 86400
if t1.Add(time.Duration(Days)*24*time.Hour).Day() != t2.Day() {
Days++
}
return int(Days)
}
func CountDivMul(t1, t2 time.Time) int {
d1 := t1.Unix() / 86400 * 86400
return int((t2.Unix() - d1) / 86400)
}
CountTrim
使用time.Time.Date
方法修剪小时和分钟等等。请注意,只需要调用TrimToDate
一次,因为剩余部分将被整数除法丢弃。
CountUnixAdd
是一种简单明了的方法:测试是否是相同的日期,如果没有,则添加一个。
CountDivMul
几乎与修剪一天的想法相同,但使用更黑客的方式:使用整数除法来消除剩余部分然后再增加。
笔记本电脑上的基准测试结果:
goos: windows
goarch: amd64
pkg: test/stackoverflow/dateprb
BenchmarkCountTrim-8 20000000 62.7 ns/op
BenchmarkCountDivMul-8 1000000000 2.12 ns/op
BenchmarkCountUnixAdd-8 20000000 77.8 ns/op
PASS
ok test/stackoverflow/dateprb 5.367s
不出所料,hack-y方式比另一方式快,而两种常用方式几乎相同。
完整代码(基准和功能)here
答案 2 :(得分:1)
有许多事情需要担心。例如,由于夏令时(DST),并非所有天都是24小时。如果时间在不同的时区怎么办?等等。
这是解决这些问题的解决方案。
package main
import (
"fmt"
"time"
)
// CalendarDays returns the calendar difference between times (t2 - t1) as days.
func CalendarDays(t2, t1 time.Time) int {
y, m, d := t2.Date()
u2 := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
y, m, d = t1.In(t2.Location()).Date()
u1 := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
days := u2.Sub(u1) / (24 * time.Hour)
return int(days)
}
func main() {
first := time.Now().Round(0)
end := first.Add(48 * time.Hour)
for last := first; last.Before(end); last = last.Add(6 * time.Hour) {
fmt.Println("Days:", CalendarDays(last, first), "Last:", last, "First:", first)
}
}
游乐场:https://play.golang.org/p/wKwQzgfKa8f
输出:
Days: 0 Last: 2018-02-05 17:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 0 Last: 2018-02-05 23:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 1 Last: 2018-02-06 05:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 1 Last: 2018-02-06 11:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 1 Last: 2018-02-06 17:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 1 Last: 2018-02-06 23:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 2 Last: 2018-02-07 05:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST
Days: 2 Last: 2018-02-07 11:38:15.623292254 -0500 EST First: 2018-02-05 17:38:15.623292254 -0500 EST