获取两个时间之间的差异时出错

huangapple go评论100阅读模式
英文:

Go: error getting difference between two time

问题

我对时间有一个问题。我有上面的代码:

// ticker := time.NewTicker(time.Minute * 1)
ticker := time.NewTicker(time.Second * 1)
defer ticker.Stop()

// new version
for t := range ticker.C {

    // 获取持续时间

    go func() {
        now := time.Now()
        const layout = "2006-01-02 15:04:05"

        endDateStr := fmt.Sprintf("%04d-%02d-%02d 23:45:00", now.Year(), now.Month(), now.Day())
        endDate, _ := time.Parse(layout, endDateStr)

        duration := endDate.Sub(now)

        drHours := (duration.Minutes() - math.Mod(duration.Minutes(), 60)) / 60
        drMinutes := math.Mod(duration.Minutes(), 60)
        //fmt.Println(duration.Hours())

        fmt.Println(now)
        fmt.Println(endDate)

        durStr := fmt.Sprintf("%d:%d:00", uint64(drHours), uint64(drMinutes))
        fmt.Printf("duration: %s\n", durStr)
    }()
    fmt.Println(t)
}

在我的计算机上,nowendDate 有不同的时区:

2015-11-12 10:33:53.9298552 +0500 UZT  // now
2015-11-12 23:45:00 +0000 UTC          // endDate

这就是为什么得到错误的持续时间。我该如何设置它们的相同时区?
还有一个问题,当 ticker 第一次和第二次触发时,持续时间相差5小时。为什么会出现这些问题?我做错了什么?你有任何想法吗?希望你能给我一些提示。

英文:

I have one headache with time. I have above code:

// ticker := time.NewTicker(time.Minute * 1)
    ticker := time.NewTicker(time.Second * 1)
	defer ticker.Stop()

	// new version
	for t := range ticker.C {

		// get duration

		go func() {
			now := time.Now()
			const layout = "2006-01-02 15:04:05"

			endDateStr := fmt.Sprintf("%04d-%02d-%02d 23:45:00", now.Year(), now.Month(), now.Day())
			endDate, _ := time.Parse(layout, endDateStr)

			duration := endDate.Sub(now)

			drHours := (duration.Minutes() - math.Mod(duration.Minutes(), 60)) / 60
			drMinutes := math.Mod(duration.Minutes(), 60)
			//fmt.Println(duration.Hours())

			fmt.Println(now)
			fmt.Println(endDate)

			durStr := fmt.Sprintf("%d:%d:00", uint64(drHours), uint64(drMinutes))
			fmt.Printf("duration: %s\n", durStr)
		}()
		fmt.Println(t)
	}

At my comp now and endDate have different time zone:

2015-11-12 10:33:53.9298552 +0500 UZT  // now
2015-11-12 23:45:00 +0000 UTC          // endDate

That's why get wrong duration. How can I set same time zone to both of them ?
And a problem again, pay attantion when ticker tik first and second duration has differens 5 hour. Why those problems have occured. What am I doing wrong? Do you have any idea ? Made me happe any hint from you ?

答案1

得分: 3

为了避免夏令时(Daylight Savings Time)和其他错误,使用协调世界时(UTC)来计算时间间隔。例如,

package main

import (
	"fmt"
	"math"
	"time"
)

func main() {
	ticker := time.NewTicker(time.Second * 1)
	defer ticker.Stop()

	for t := range ticker.C {
		go func() {
			now := time.Now().UTC()

			const layout = "2006-01-02 15:04:05"
			endDateStr := fmt.Sprintf("%04d-%02d-%02d 23:45:00", now.Year(), now.Month(), now.Day())
			endDate, _ := time.Parse(layout, endDateStr)

			duration := endDate.Sub(now)
			drMinutes := math.Mod(duration.Minutes(), 60)
			drHours := (duration.Minutes() - drMinutes) / 60

			fmt.Println(now)
			fmt.Println(endDate)

			durStr := fmt.Sprintf("%d:%d:00", uint64(drHours), uint64(drMinutes))
			fmt.Printf("duration: %s\n", durStr)
		}()
		fmt.Println(t.UTC())
	}
}

输出:

2015-11-12 06:41:40.123232567 +0000 UTC
2015-11-12 06:41:40.123409615 +0000 UTC
2015-11-12 23:45:00 +0000 UTC
duration: 17:3:00
英文:

To avoid DST (Daylight Savings Time) and other errors use UTC for the duration. For example,

package main

import (
	"fmt"
	"math"
	"time"
)

func main() {
	ticker := time.NewTicker(time.Second * 1)
	defer ticker.Stop()

	for t := range ticker.C {
		go func() {
			now := time.Now().UTC()

			const layout = "2006-01-02 15:04:05"
			endDateStr := fmt.Sprintf("%04d-%02d-%02d 23:45:00", now.Year(), now.Month(), now.Day())
			endDate, _ := time.Parse(layout, endDateStr)

			duration := endDate.Sub(now)
			drMinutes := math.Mod(duration.Minutes(), 60)
			drHours := (duration.Minutes() - drMinutes) / 60

			fmt.Println(now)
			fmt.Println(endDate)

			durStr := fmt.Sprintf("%d:%d:00", uint64(drHours), uint64(drMinutes))
			fmt.Printf("duration: %s\n", durStr)
		}()
		fmt.Println(t.UTC())
	}
}

Output:

2015-11-12 06:41:40.123232567 +0000 UTC
2015-11-12 06:41:40.123409615 +0000 UTC
2015-11-12 23:45:00 +0000 UTC
duration: 17:3:00

答案2

得分: 1

peterSO的答案是正确的。我用上面的代码解决了这个问题:

endDate := time.Date(now.Year(), now.Month(), now.Day(), 23, 45, 0, now.Nanosecond(), now.Location())

如果有人遇到类似的问题,他们可以选择其中之一。

英文:

peterSO's answer is right. And I solved the problem with above code:

endDate := time.Date(now.Year(), now.Month(), now.Day(), 23, 45, 0, now.Nanosecond(), now.Location())

If somebody come accross with a problem like that they can choose ine of them.

huangapple
  • 本文由 发表于 2015年11月12日 13:54:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/33665244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定