Golang中日期间隔差值的比较方法

Golang中日期间隔差值的比较方法 我的代码在这里 Go Playground - The Go Programming Language。我的做法是,首先获取本地时间,然后根据本地时间将其转换为指定时区的时间。接着我进行比较,我想知道第二个日期(在我的代码中指的是 dateNewFormat)是否已经跨越到了新的一天。我使用的比较方法是:result := dateExistFormat.Truncate(24 * time.Hour).Compare(dateNewFormat.Truncate(24 * time.Hour))。如果 dateNewFormat 已经跨越到了新的一天,那么这个比较结果应该显示不同。但目前的比较结果仍然是 0。什么是正确的方法来比较两个日期本身是否不同(仅基于日期,不考虑时间)?另外,我还想了解如何仅基于日期值(不考虑时间)来计算这两个日期之间相差的天数。


更多关于Golang中日期间隔差值的比较方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

好的,Jeff, 这看起来没问题。但是,假设我想知道天数差异,你有什么建议吗?因为我看到有一个 Sub 函数可以工作,但它是通过那种格式和解析方法实现的。

更多关于Golang中日期间隔差值的比较方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 Mje,

是的,我正在使用这个包。我不太明白你这句话的意思:“Truncate 操作的是时间作为自零时刻以来的绝对时长;它并不操作时间的表示形式。”?

time.Sub(以及 Add)方法会正常工作。只有 TruncateRound 方法是相对于零时间(zero time)进行操作的。

好的,我将为您将提供的HTML内容转换为Markdown格式,并严格遵守您提出的所有规则。

你好 Jeff,

感谢你的确认。我会尽快对所有内容进行测试,并确定正确的方法。

我找到了这个方法 dateExistDay, error := time.Parse("2006-01-02", dateExistFormat.String()[0:10]). 在转换之后,我进一步进行解析,这次只是为了获取日期,看起来是可行的。

对于同一时区的日期,这个方法是否有效?

func sameDay(date1,date2 time.Time) bool {
  y1, m1, d1 := date1.Date()
  y2, m2, d2 := date2.Date()
  return y1==y2 && m1==m2 && d1==d2
}

这样可以省去格式化和解析的来回转换。

pkg.go.dev

time 包 - time - Go Packages

time 包提供了测量和显示时间的功能。

Truncate 方法将时间作为自零时刻以来的绝对持续时间进行操作;它并不操作时间的表示形式。

time.Time 表示自 UTC 时间 1970 年 1 月 1 日午夜以来的毫秒数。文档中的引述“自零时间的绝对持续时间”指的就是这个意思。将你的时间以 UTC 格式打印出来,就能看到它们相对于零时间是在同一天。

favicon.ico

time package - time - Go Packages

Package time provides functionality for measuring and displaying time.

Time 类型的零值是 UTC 时间公元 1 年 1 月 1 日 00:00:00.000000000。

要比较两个时间值的日期部分是否相同,以及计算日期之间的天数差,你需要使用 time.TimeYear()Month()Day() 方法来提取日期部分。以下是两种常见的方法:

方法1:比较日期是否相同

package main

import (
    "fmt"
    "time"
)

func sameDate(t1, t2 time.Time) bool {
    y1, m1, d1 := t1.Date()
    y2, m2, d2 := t2.Date()
    return y1 == y2 && m1 == m2 && d1 == d2
}

func main() {
    // 示例时间
    t1 := time.Date(2024, 1, 15, 14, 30, 0, 0, time.UTC)
    t2 := time.Date(2024, 1, 15, 23, 59, 59, 0, time.UTC)
    t3 := time.Date(2024, 1, 16, 0, 0, 1, 0, time.UTC)
    
    fmt.Println("t1和t2同一天:", sameDate(t1, t2)) // true
    fmt.Println("t1和t3同一天:", sameDate(t1, t3)) // false
}

方法2:计算日期之间的天数差

package main

import (
    "fmt"
    "time"
)

func daysBetween(t1, t2 time.Time) int {
    // 将两个时间都转换为当天的0点
    y1, m1, d1 := t1.Date()
    y2, m2, d2 := t2.Date()
    
    date1 := time.Date(y1, m1, d1, 0, 0, 0, 0, time.UTC)
    date2 := time.Date(y2, m2, d2, 0, 0, 0, 0, time.UTC)
    
    // 计算天数差
    hours := date2.Sub(date1).Hours()
    days := int(hours / 24)
    
    if days < 0 {
        days = -days
    }
    
    return days
}

func main() {
    // 示例时间
    t1 := time.Date(2024, 1, 15, 14, 30, 0, 0, time.UTC)
    t2 := time.Date(2024, 1, 16, 0, 0, 1, 0, time.UTC)
    t3 := time.Date(2024, 1, 20, 23, 59, 59, 0, time.UTC)
    
    fmt.Println("t1和t2相差天数:", daysBetween(t1, t2)) // 1
    fmt.Println("t1和t3相差天数:", daysBetween(t1, t3)) // 5
}

针对时区问题的完整示例

package main

import (
    "fmt"
    "time"
)

func truncateToDate(t time.Time) time.Time {
    y, m, d := t.Date()
    return time.Date(y, m, d, 0, 0, 0, 0, t.Location())
}

func main() {
    // 创建不同时区的时间
    loc, _ := time.LoadLocation("America/New_York")
    t1 := time.Date(2024, 1, 15, 23, 30, 0, 0, loc)  // 纽约时间
    t2 := time.Date(2024, 1, 16, 4, 30, 0, 0, time.UTC) // UTC时间
    
    // 转换为日期
    date1 := truncateToDate(t1)
    date2 := truncateToDate(t2)
    
    fmt.Println("原始时间1:", t1)
    fmt.Println("原始时间2:", t2)
    fmt.Println("日期1:", date1)
    fmt.Println("日期2:", date2)
    
    // 比较日期
    if date1.Equal(date2) {
        fmt.Println("两个时间在同一天")
    } else {
        fmt.Println("两个时间不在同一天")
    }
    
    // 计算天数差
    hours := date2.Sub(date1).Hours()
    days := int(hours / 24)
    if days < 0 {
        days = -days
    }
    fmt.Printf("相差天数: %d\n", days)
}

在你的代码中,Truncate(24 * time.Hour) 方法的问题在于它只是截断到最近的小时倍数,而不是真正截断到当天的开始。正确的方法是使用 Date() 方法提取年月日,然后重新构造一个时间为当天的0点。

回到顶部