计算 N 天前的日期,可否用时间戳直接减? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hunk
V2EX    C++

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

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

    为何我相减后,输出时间都是减了 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 年月日是应该不会受闰秒影响
    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     Solana     3563 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:12 PVG 08:12 LAX 16:12 JFK 19:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86