The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
Junjunya

go 语言时间比较,可以直接比较时间字符串????

  •  
  •   Junjunya · Mar 28, 2019 · 9825 views
    This topic created in 2783 days ago, the information mentioned may be changed or developed.

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

    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
    }
    

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

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

    19 replies  •  2019-03-29 09:36:37 +08:00
    www5070504
    www5070504
    Mar 28, 2019
    1
    按 ascii 码逐个字符比较?
    dremy
    dremy
    Mar 28, 2019 via iPhone
    2
    ascii 比较呗,肯定是能比的
    cpdyj0
    cpdyj0
    Mar 28, 2019
    3
    没用过 Go,处理 ASCII 比较,会不会是运算符重载之类的?(不知道 Go 有没有这种东西)
    mengzhuo
    mengzhuo
    Mar 28, 2019
    4
    字符比较,按 ascii,当然可以啦,效率嘛……比 time.Time 慢至少 2 倍多

    不过有些特殊情况就搞不定了,比如说两个不同时区的时间比较~(虽然国内程序员很少遇到)
    misaka19000
    misaka19000
    Mar 28, 2019
    5
    某些情况下是能比较的,不过能写出这种代码的程序员水平也真是拙计
    liyunlong41
    liyunlong41
    Mar 28, 2019 via iPhone
    6
    @mengzhuo 有 benchmarks 吗?很好奇为啥会慢
    pwrliang
    pwrliang
    Mar 28, 2019 via Android
    7
    逐个字符比较呗,SQL 里经常这么写,感觉会比转换成日期类型还快
    Erskine
    Erskine
    Mar 28, 2019 via Android
    8
    有才华 比解析一遍时间来的效率
    blankme
    blankme
    Mar 28, 2019 via Android
    9
    @liyunlong41
    timestamp 比较只需要比一次数字,string 比较的话,一个一个字符比。。。
    petelin
    petelin
    Mar 28, 2019 via iPhone
    10
    @blankme 难道不要计算构造 time 对象的花销?
    azh7138m
    azh7138m
    Mar 28, 2019
    11
    @petelin 时间戳是个数字,直接比较,构建啥 time 对象?
    gamexg
    gamexg
    Mar 28, 2019❤️1
    12
    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
    blankme
    blankme
    Mar 28, 2019❤️1
    13
    @petelin
    其实要省时间可以把那串时间直接写成数字,然后边上注释一下
    (不过 9102 年了,干这种事没什么意义
    laminux29
    laminux29
    Mar 28, 2019❤️2
    14
    [YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,能进行比较的本质原因,是因为该字符串是一种 [进位数值系统] 。

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

    而 [YYYY-MM-dd HH:mm:ss.fff] 格式的字符串,也是进位的数值系统,只是它的进位是非固定的,比如时分位是右位 12 进 1,但月位却是右位 28、30、31 进 1。
    yippees
    yippees
    Mar 28, 2019
    15
    now 也是 time.Now()转的吧,转换成数字比较更快吧
    如果涉及到金钱相关,跨个时区
    WilliamYang
    WilliamYang
    Mar 28, 2019
    16
    这个时间格式本来就不带有时区, 当然可以这样比较啊
    skiy
    skiy
    Mar 28, 2019
    17
    ...
    我一般是转成时间戳再比较的,我是不是做错了?
    wweir
    wweir
    Mar 29, 2019 via iPhone
    18
    @skiy 那怎么转换成时间戳呢?不构建 time 对象生撸?
    mengzhuo
    mengzhuo
    Mar 29, 2019❤️1
    19
    @blankme 并不是,Go 会用 AVX 并行优化这部分代码,而字符串时间是 19 个字节,19*8 = 152 < 256。一次比较就能得出结果。大概率是慢在内存加载上(懒得做分析了,摊手~

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

    差别嘛~自己看 objdump 吧

    ```
    func BenchmarkISOString(b *testing.B) {
    a := "2019-04-10 19:00:00"
    c := "2019-04-10 19:00:01"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = a < c
    }
    }

    func BenchmarkTime(b *testing.B) {
    a := time.Now()
    c := time.Now().Add(time.Second)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = a.Before(c)
    }
    }


    goos: linux
    goarch: amd64
    BenchmarkISOString-12 200000000 6.68 ns/op
    BenchmarkISOString-12 200000000 6.71 ns/op
    BenchmarkISOString-12 200000000 6.55 ns/op
    BenchmarkTime-12 500000000 3.89 ns/op
    BenchmarkTime-12 500000000 4.07 ns/op
    BenchmarkTime-12 500000000 3.93 ns/op
    PASS
    ok _/root/hoho 13.189s
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4505 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 59ms · UTC 06:09 · PVG 14:09 · LAX 22:09 · JFK 01:09
    ♥ Do have faith in what you're doing.