Golang中如何判断给定日期是否在两个日期之间

Golang中如何判断给定日期是否在两个日期之间 我正在尝试创建一个函数,用于判断当前日期是否介于两个给定日期之间? 例如,我有一条记录,其生效日期为 01-01-2010,失效日期为 11-30-2025,我想判断 11-01-2015 是否在这两个日期之间?如果是,函数返回 true,否则返回 false。 有什么建议吗?

8 回复

看起来,如果两个时间都包含单调时钟时间,时间比较会使用单调时钟。你可以使用 time.Time.Round(0) 来移除单调时钟时间。

func main() {
    fmt.Println("hello world")
}

更多关于Golang中如何判断给定日期是否在两个日期之间的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


avatar skillian:

你好 @skillian

这段代码能同时处理两种时钟时间(挂钟时间和单调时间)吗?

此外,在序列化 time.Time 对象时,是否只有挂钟时间会被序列化?——这句话对吗? 还有,挂钟时间和单调时钟在内存中都是 int32 类型的值吗?——我这样理解对吗?

这是我不太清楚的 Go 语言主题之一。

您还可以使用 time.Time.Aftertime.Time.Beforetime.Time.Equal 方法:

func TimeIsBetween(t, min, max time.Time) bool {
    if min.After(max) {
        min, max = max, min
    }
    return (t.Equal(min) || t.After(min)) && (t.Equal(max) || t.Before(max))
}

skillian:

你好 @skillian

如果我理解有误,请纠正我:在上面的代码中,我想强制规定所有比较只考虑挂钟时间。因此,我可以在该函数的开头添加:

t.stripMono()
min.stripMono()
max.stripMono()

这是因为挂钟时间不受运行代码的机器上时间速度变化的影响。我找不到挂钟和单调钟之间差异的实际例子。

在我脑海中,我认为挂钟时间是:“2020-01-01 05:30:23”,而单调钟时间是 1424322134。这种想法很愚蠢,因为两种时钟的时间都可以用同样的两种格式表示。有没有什么实际的方法可以可视化单调钟和挂钟之间的区别?有任何例子吗?

JOhn_Stuart:

此外,在序列化一个 time.Time 对象时,只有挂钟时间会被序列化吗?

你所说的“序列化”具体指什么?如果你指的是 String 函数,那么不是的,单调时钟也会被包含在内:Go Playground - The Go Programming Language

JOhn_Stuart:

挂钟和单调时钟在内存中都是 int32 类型的值吗?

Go 语言最棒的一点是,当你找到一个类型的文档(例如 time.Time)时,你可以点击文档中的标题,它会带你跳转到源代码

单调时钟旨在确定事件的相对顺序。挂钟时间可以被调整以考虑闰秒(或任何其他原因)。如果你有这样的代码:

startTime := time.Now()
doSomething()
endTime := time.Now()

那么 startTime.Before(endTime) 将始终返回 true。如果你这样做:

startTime := time.Now().Round(0)
doSomething()
endTime := time.Now().Round(0)

现在,如果在设置 startTimeendTime 之间发生了闰秒或其他时间变更,startTime.Before(endTime) 可能会返回 false

如果你不是使用 time.Now 来创建时间,那么 time.Time 将不包含单调时钟成分,时间比较将使用挂钟/日历时间进行比较。无论哪种情况,我相信 TimeIsBetween 对于单调时钟或挂钟(或两者)都应该表现正确。

在Go语言中,可以使用time包来处理日期比较。以下是一个函数示例,用于判断给定日期是否在两个日期之间:

package main

import (
    "fmt"
    "time"
)

func isDateBetween(checkDate, startDate, endDate time.Time) bool {
    return (checkDate.Equal(startDate) || checkDate.After(startDate)) && 
           (checkDate.Equal(endDate) || checkDate.Before(endDate))
}

func main() {
    // 定义日期格式
    layout := "01-02-2006"
    
    // 解析日期
    start, _ := time.Parse(layout, "01-01-2010")
    end, _ := time.Parse(layout, "11-30-2025")
    check, _ := time.Parse(layout, "11-01-2015")
    
    // 检查日期是否在范围内
    result := isDateBetween(check, start, end)
    fmt.Printf("日期 %v 在 %v 和 %v 之间: %v\n", 
        check.Format(layout), 
        start.Format(layout), 
        end.Format(layout), 
        result)
}

如果希望包含边界日期(即检查日期等于开始或结束日期时返回true),可以使用以下函数:

func isDateBetweenInclusive(checkDate, startDate, endDate time.Time) bool {
    return !checkDate.Before(startDate) && !checkDate.After(endDate)
}

对于需要处理时区的情况:

func isDateBetweenWithLocation(checkDateStr, startDateStr, endDateStr string) (bool, error) {
    layout := "01-02-2006"
    loc, _ := time.LoadLocation("UTC")
    
    start, err := time.ParseInLocation(layout, startDateStr, loc)
    if err != nil {
        return false, err
    }
    
    end, err := time.ParseInLocation(layout, endDateStr, loc)
    if err != nil {
        return false, err
    }
    
    check, err := time.ParseInLocation(layout, checkDateStr, loc)
    if err != nil {
        return false, err
    }
    
    return !check.Before(start) && !check.After(end), nil
}

使用示例:

func main() {
    // 示例1:基本用法
    layout := "01-02-2006"
    start, _ := time.Parse(layout, "01-01-2010")
    end, _ := time.Parse(layout, "11-30-2025")
    
    // 测试不同日期
    testDates := []string{
        "11-01-2015",
        "12-01-2025",
        "01-01-2010",
        "11-30-2025",
        "12-01-2025",
    }
    
    for _, dateStr := range testDates {
        check, _ := time.Parse(layout, dateStr)
        result := isDateBetween(check, start, end)
        fmt.Printf("%s 在范围内: %v\n", dateStr, result)
    }
    
    // 示例2:带时区处理
    result, err := isDateBetweenWithLocation("11-01-2015", "01-01-2010", "11-30-2025")
    if err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Println("带时区检查结果:", result)
    }
}

输出结果:

11-01-2015 在范围内: true
12-01-2025 在范围内: false
01-01-2010 在范围内: true
11-30-2025 在范围内: true
12-01-2025 在范围内: false
带时区检查结果: true

注意:Go的time.Parse函数使用特定格式"01-02-2006 15:04:05"作为参考日期,这是Go语言的标准日期格式。

回到顶部