V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hunk
V2EX  ›  C++

计算 N 天前的日期,可否用时间戳直接减?

  •  
  •   hunk · 2022-09-15 08:18:35 +08:00 · 4122 次点击
    这是一个创建于 800 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为何我相减后,输出时间都是减了 10 天,是指针问题? now 和 s_tm 声明为两个变量了,求指教。

    time_t now = time(0);
    
    tm *e_lt = gmtime(&now);
    time_t s_tm = time(0);
    
    s_tm -=60*60*24*10;
    
    tm *s_lt = gmtime(&s_tm);
    
    23 条回复    2022-09-16 17:29:51 +08:00
    BrettD
        1
    BrettD  
       2022-09-15 08:53:58 +08:00 via iPhone
    gmtime 返回的指针指向的那片 tm 结构体是全局共享的,也就是说两次 gmtime 调用会返回同一个地址,第二次 gmtime 把第一次的结果覆盖了
    BrettD
        2
    BrettD  
       2022-09-15 08:54:48 +08:00 via iPhone
    加减时间戳是可以的,只是你要换一种方式去字符串化时间戳
    ericls
        3
    ericls  
       2022-09-15 09:08:51 +08:00 via iPhone
    有闰秒
    ericls
        4
    ericls  
       2022-09-15 09:09:23 +08:00 via iPhone
    还有夏令时
    sparklee
        5
    sparklee  
       2022-09-15 09:24:42 +08:00
    本来就是直接时间戳想减
    julyclyde
        6
    julyclyde  
       2022-09-15 09:26:17 +08:00
    @ericls 说的对
    anytk
        7
    anytk  
       2022-09-15 09:52:26 +08:00   ❤️ 1
    unix 时间戳直接加减时可以的,因为 unix 时间不考虑闰秒和夏令时,绝对时间轴,每天就是 24 * 60 * 60 秒。
    也可以通过 struct tm 结构成员操作来计算偏移时间。
    securityCoding
        8
    securityCoding  
       2022-09-15 10:01:24 +08:00   ❤️ 1
    Unix 时间戳是从 1970 年 1 月 1 日( UTC/GMT 的午夜)开始所经过的秒数,不考虑闰秒。
    hunk
        9
    hunk  
    OP
       2022-09-15 10:10:08 +08:00 via iPhone
    谢谢各位,全局共享,这下记住了。换换其他方法
    billgong
        10
    billgong  
       2022-09-15 11:01:15 +08:00
    @securityCoding 但实际显示和计算需要考虑闰秒,所以是有影响的
    L4Linux
        11
    L4Linux  
       2022-09-15 11:24:14 +08:00
    anytk
        12
    anytk  
       2022-09-15 13:41:30 +08:00
    @billgong 显示也是不考虑的,闰秒的播发是通过网络或者 GPS ,比如 NTP 时间同步这些,核心是纠正真实时间与 UTC 时间的偏差。Unix 时间戳可以看作是 UTC 的一种表达方式而已。
    显示是根据当地时区夏令时来计算的。
    想详细了解可以看看初步的 GPS 时间设计。
    dangyuluo
        13
    dangyuluo  
       2022-09-15 13:47:06 +08:00
    然后再考虑一下夏令时
    adoal
        14
    adoal  
       2022-09-15 13:53:54 +08:00
    提醒一下认为用 timestamp 则不用考虑闰秒和夏令时的人:“N 天前的日期” 是一个人为的历法概念,给天的日期编一个序号,往前倒数 N 个序号,而不是物理概念。历法里的每个“天”的长度不一定正好是 24*60*60 秒,算天数本质上只考虑日期的序号,不管每天长度是多少,都算作平等的一。
    mxT52CRuqR6o5
        15
    mxT52CRuqR6o5  
       2022-09-15 14:21:38 +08:00
    https://en.wikipedia.org/wiki/Unix_time
    我读了下 wiki ,我理解 unix 时间戳转 utc 年月日是受闰秒影响的
    mxT52CRuqR6o5
        16
    mxT52CRuqR6o5  
       2022-09-15 14:23:54 +08:00
    @anytk
    按照维基百科的说法,如果我没理解错的话,Unix 时间戳并不是 UTC 的一种表达方式,是会受到闰秒影响的
    mxT52CRuqR6o5
        17
    mxT52CRuqR6o5  
       2022-09-15 14:36:40 +08:00
    我又仔细读了几遍 wiki ,我上面的结论有点问题,虽然 Unix 时间戳并不是 UTC 的一种表达方式,但 unix 时间戳转 utc 年月日是应该不会受闰秒影响
    https://www.v2ex.com/t/706585
    『正闰秒会出现一个 UNIX time 对应两个 UTC time ,负闰秒(从未发生)会导致一个 UNIX time 没有对应的 UTC time 』
    julyclyde
        18
    julyclyde  
       2022-09-16 09:00:45 +08:00
    @anytk 显示的时候是根据 tzdata 计算的
    tzdata 是考虑闰秒和历法变动的
    julyclyde
        19
    julyclyde  
       2022-09-16 09:01:00 +08:00
    @mxT52CRuqR6o5 你的理解错误
    mxT52CRuqR6o5
        20
    mxT52CRuqR6o5  
       2022-09-16 11:16:09 +08:00 via Android
    @julyclyde 正润秒会让一天内的某一分钟有 61 秒(对应 unix 时间戳的 60 秒,unix 的某个时间戳会有两个对应的 utc 时间),一天内的其他时间和年月日是感受不到这个润秒的,我这个理解是哪里有问题?
    julyclyde
        21
    julyclyde  
       2022-09-16 12:38:22 +08:00
    @mxT52CRuqR6o5 用闰秒公布之前和之后的两个版本的 tzdata 去解读闰秒之后的同一个 timestamp 会得到不同的 utc 时间
    mxT52CRuqR6o5
        22
    mxT52CRuqR6o5  
       2022-09-16 12:50:04 +08:00
    @julyclyde
    按照 wiki 上举的那个例子,正闰秒多出来的那一秒会和上一个 utc 秒拥有同一个 unix 时间戳,不应该会出现你说的这种情况啊
    julyclyde
        23
    julyclyde  
       2022-09-16 17:29:51 +08:00
    @mxT52CRuqR6o5 你找个闰秒时刻,按照我给你的两种条件,双向计算一下试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2504 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:12 · PVG 09:12 · LAX 17:12 · JFK 20:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.