Golang Go语言中时间比较,可以直接比较时间字符串????

Golang Go语言中时间比较,可以直接比较时间字符串????

看到同事这么写的时间比较

if now < "2019-04-10 19:00:00" {
    result["isDo"] = 0
}else if now > "2019-04-11 00:00:00"  {
    result["isDo"] = 2
}else {
    result["isDo"] = 1
}

震惊了,居然可以这么写。自己试了下,可以比较

但是网上搜索了一下,居然没找到相关的说明。想知道这样写的原理是什么


更多关于Golang Go语言中时间比较,可以直接比较时间字符串????的实战教程也可以访问 https://www.itying.com/category-94-b0.html

20 回复

按 ascii 码逐个字符比较?

更多关于Golang Go语言中时间比较,可以直接比较时间字符串????的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


ascii 比较呗,肯定是能比的

没用过 Go,处理 ASCII 比较,会不会是运算符重载之类的?(不知道 Go 有没有这种东西)

字符比较,按 ascii,当然可以啦,效率嘛……比 time.Time 慢至少 2 倍多

不过有些特殊情况就搞不定了,比如说两个不同时区的时间比较~(虽然国内程序员很少遇到)

某些情况下是能比较的,不过能写出这种代码的程序员水平也真是拙计

有 benchmarks 吗?很好奇为啥会慢

逐个字符比较呗,SQL 里经常这么写,感觉会比转换成日期类型还快

有才华 比解析一遍时间来的效率


timestamp 比较只需要比一次数字,string 比较的话,一个一个字符比。。。

难道不要计算构造 time 对象的花销?

时间戳是个数字,直接比较,构建啥 time 对象?

package main

import (
“fmt”
“time”
)

func main() {
testData := “2006-01-02 15:04:05”

nowStr := time.Now().Format(“2006-01-02 15:04:05”)
f1 := func() bool {
return testData > nowStr
}

f2 := func() bool {
nowStr := time.Now().Format(“2006-01-02 15:04:05”)
return testData > nowStr
}

f3 := func() bool {
t, err := time.Parse(“2006-01-02 15:04:05”, testData)
if err != nil {
panic(err)
}
return time.Now().After(t)
}

T(“字符串比较”, f1)
T(“now 转换为字符串后和字符串比较”, f2)
T(“字符串解析为 time 后比较”, f3)

}

func T(name string, f func() bool) {
s := time.Now()
for i := 0; i < 1000000; i++ {
f()
}
fmt.Printf("%v 耗时 %v\r\n", name, time.Now().Sub(s))
}

字符串比较 耗时 5.0145ms
now 转换为字符串后和字符串比较 耗时 203.3878ms
字符串解析为 time 后比较 耗时 190.563ms


其实要省时间可以把那串时间直接写成数字,然后边上注释一下
(不过 9102 年了,干这种事没什么意义

[YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,能进行比较的本质原因,是因为该字符串是一种 [进位数值系统] 。

整数 123456 这种是以 10 作为进位的数值系统,它能进行比较。

而 [YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,也是进位的数值系统,只是它的进位是非固定的,比如时分位是右位 12 进 1,但月位却是右位 28、30、31 进 1。

now 也是 time.Now()转的吧,转换成数字比较更快吧
如果涉及到金钱相关,跨个时区

这个时间格式本来就不带有时区, 当然可以这样比较啊


我一般是转成时间戳再比较的,我是不是做错了?

那怎么转换成时间戳呢?不构建 time 对象生撸?

并不是,Go 会用 AVX 并行优化这部分代码,而字符串时间是 19 个字节,19*8 = 152 < 256。一次比较就能得出结果。大概率是慢在内存加载上(懒得做分析了,摊手~

嗯,有探索精神,可惜懒了点。
我跑了跑,不是 2 倍( 100%),是~70%。

差别嘛~自己看 objdump 吧

<br>func BenchmarkISOString(b *testing.B) {<br> a := "2019-04-10 19:00:00"<br> c := "2019-04-10 19:00:01"<br> b.ResetTimer()<br> for i := 0; i &lt; b.N; i++ {<br> _ = a &lt; c<br> }<br>}<br><br>func BenchmarkTime(b *testing.B) {<br> a := time.Now()<br> c := time.Now().Add(time.Second)<br> b.ResetTimer()<br> for i := 0; i &lt; b.N; i++ {<br> _ = a.Before(c)<br> }<br>}<br><br><br>goos: linux<br>goarch: amd64<br>BenchmarkISOString-12 200000000 6.68 ns/op<br>BenchmarkISOString-12 200000000 6.71 ns/op<br>BenchmarkISOString-12 200000000 6.55 ns/op<br>BenchmarkTime-12 500000000 3.89 ns/op<br>BenchmarkTime-12 500000000 4.07 ns/op<br>BenchmarkTime-12 500000000 3.93 ns/op<br>PASS<br>ok _/root/hoho 13.189s<br>

在Golang(Go语言)中,直接比较时间字符串并不是一个推荐的做法,因为这样做既不安全也不高效。时间字符串的格式可能多样,如"2023-04-01T12:00:00Z""04/01/2023 12:00:00"等,不同的格式不仅可能导致比较结果不准确,还容易引发解析错误。

Go语言提供了强大的time包来处理时间相关的操作。要正确比较两个时间,首先应将时间字符串解析为time.Time类型。例如:

package main

import (
    "fmt"
    "time"
)

func main() {
    layout := "2006-01-02 15:04:05"
    t1, err1 := time.Parse(layout, "2023-04-01 12:00:00")
    t2, err2 := time.Parse(layout, "2023-03-01 12:00:00")
    
    if err1 != nil || err2 != nil {
        fmt.Println("Error parsing time")
        return
    }
    
    if t1.After(t2) {
        fmt.Println("t1 is after t2")
    } else {
        fmt.Println("t1 is not after t2")
    }
}

在这个例子中,我们首先定义了时间格式layout,然后使用time.Parse将时间字符串解析为time.Time对象,最后通过AfterBeforeEqual方法进行比较。这种方法不仅准确,而且充分利用了Go语言类型系统的优势,避免了潜在的错误和性能问题。

回到顶部