尴尬了,我连根据秒数来计算天数差值都搞不定,求解! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wl879
V2EX    问与答

尴尬了,我连根据秒数来计算天数差值都搞不定,求解!

  •  
  •   wl879 2017-06-22 02:52:13 +08:00 4518 次点击
    这是一个创建于 3072 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是我笨蛋了吗, 计算天数是不是用 “时间戳 / (60 秒 * 60 分 * 24 小时)” (单位是秒)

    先请问是我这公式不对吗,如果对,可我计算出来会有问题,如:

    2017.6.1 07:00 与 2017.6.1 09:00 所得结果会多出 1 天,什么原因

    why,why,why

    28 条回复    2017-06-22 17:39:41 +08:00
    Perry
        1
    Perry  
       2017-06-22 02:56:14 +08:00
    为啥不把数据列出来
    SharkIng
        2
    SharkIng  
       2017-06-22 03:17:54 +08:00 via iPhone
    确定时间戳是以秒计数的么?
    cxbig
        3
    cxbig  
       2017-06-22 03:34:21 +08:00
    系统环境和配置未知,用什么语言未知,用什么日期库或运算方法未知。
    不知道怎么帮你。
    lzdhlsc
        4
    lzdhlsc  
       2017-06-22 03:36:03 +08:00
    2017.6.1 07:00 CST = 2017.5.31 23:00 UTC
    2017.6.1 09:00 CST = 2017.6.1 01:00 UTC
    时间戳一般是以 1970.01.01 00:00 UTC 为基准的,记录的是从基准时间过了多少秒(毫秒).
    TtiGeR
        5
    TtiGeR  
       2017-06-22 07:46:41 +08:00 via iPhone
    没考虑时区吧
    xyjtou
        6
    xyjtou  
       2017-06-22 07:56:08 +08:00 via Android
    一般语言时间计算都有标准库吧,不用手工造轮
    wl879
        7
    wl879  
    OP
       2017-06-22 08:00:18 +08:00
    其实用什么语言无关,我原本用 swift (是秒为单位),为方便我用 Javascript 列一下

    var time1 = new Date("2017-6-1 7:00:00");
    var time2 = new Date("2017-6-1 9:00:00");

    console.log(time1, time1.getTime() / (60*60*24*1000))

    // 输出:Thu Jun 01 2017 07:00:00 GMT+0800 (CST) 17317.958333333332

    console.log(time2, time2.getTime() / (60*60*24*1000))

    // 输出:Thu Jun 01 2017 09:00:00 GMT+0800 (CST) 17318.041666666668

    在补充一点,其实分割点是 8:00, 大于等于 8:00 就多了一天
    wl879
        8
    wl879  
    OP
       2017-06-22 08:07:37 +08:00
    @lzdhlsc @TtiGeR 请问,时间戳是 1970.01.01 00:00 UTC 过了多少秒,然后用秒数去计算过了多少天,而不是计算具体的日期,应该与时区无关吧,请揪正一下错误,网上看了很多博客文章是教如何计算的,可测过以后,都是错的,多耽误人啊
    Pitttttt
        9
    Pitttttt  
       2017-06-22 08:14:36 +08:00 via Android
    @wl879 GMT+800 都告诉你了时区啦,基准为 12 点我们这就是 8 点,当然在你看来就是已 8 点为分界线的啊
    0ZXYDDu796nVCFxq
        10
    0ZXYDDu796nVCFxq  
       2017-06-22 08:15:04 +08:00
    timestamp 是无时区的
    你在转换时没有把时区考虑进去
    7 点和 9 点,如果你的时区是东八区,换成 GMT 在日期上刚好相差 1 天
    wl879
        11
    wl879  
    OP
       2017-06-22 08:29:20 +08:00
    @Pitttttt @gstqc 没太懂,如果 timestamp 是无时区的, 我需求计算的是 过了多少天数, 而不是几月几号,与时区还有关吗,求一下具体的计算方法
    Rice
        12
    Rice  
       2017-06-22 08:36:54 +08:00
    计算结果不是 2 小时吗??
    Rice
        13
    Rice  
       2017-06-22 08:37:21 +08:00
    @Rice #12 哦哦,我看错了
    0ZXYDDu796nVCFxq
        14
    0ZXYDDu796nVCFxq  
       2017-06-22 08:40:39 +08:00 via iPhone
    @wl879 因为你用你本地的时间就带时区了。
    比如中国的 22 号早上 7 点,在 GMT 的时区那还是 21 号 23 点,日期就相差 1 了啊
    XYxe
        15
    XYxe  
       2017-06-22 08:41:29 +08:00
    你用 (time2.getTime() - time1.getTime()) / (60*60*24*1000) 得到的就是你想要的结果了。
    先转成天数就用的是 UTC 时间的天数了。
    Pitttttt
        16
    Pitttttt  
       2017-06-22 08:41:44 +08:00 via Android
    @wl879 算出来的没时区,但是你现在是+8 就是东 8 区,他会再算到你现在在的时区,就是要+8
    0ZXYDDu796nVCFxq
        17
    0ZXYDDu796nVCFxq  
       2017-06-22 08:43:41 +08:00 via iPhone
    再说楼主的需求
    只是算个天数,直接 日期减去 1970-01-01 就行了啊
    在时区和无时区之间换算多麻烦
    Rice
        18
    Rice  
       2017-06-22 08:43:42 +08:00
    难道不是换算成 GMT 刚好是 23 点和 1 点,正好过一天?
    Rice
        19
    Rice  
       2017-06-22 08:44:23 +08:00
    Rice
        20
    Rice  
       2017-06-22 08:53:10 +08:00

    这样就好了
    Rice
        21
    Rice  
       2017-06-22 08:56:29 +08:00
    @Rice #20 操,时区……算了
    stillness
        22
    stillness  
       2017-06-22 09:04:17 +08:00   1
    这好像不是个关于时间,更不关于时区的问题

    不提这样算天数差值好不好。

    光看 那个结果,没多出一天啊,17318.041666666668 - 17317.958333333332 怎么大于 1 了,明明是 0.08333333333575865 (天)

    0.08333333333575865 * 60 * 60 * 24 = 7200。7200 秒,两小时,7 点到 9 点
    oicebot
        23
    oicebot  
       2017-06-22 09:05:32 +08:00
    是我没睡醒,还是楼主的问题描述有歧义?

    到底是问“这两个时间戳的日期差值” 还是“这两个时间戳之间差了多少天”?

    如果说是两个时间戳的日期差值,那才是分别把秒换算成 UTC 日期,然后日期相减得出差值……

    如果说差了多少天,那肯定是先相减算出差了多少秒,再把秒换算成天(时间长度单位)吧?
    lifanxi
        24
    lifanxi  
       2017-06-22 09:07:10 +08:00   1
    你那个算法里面假设了太多的东西,表面上看就是个时区的问题,实际上还有别的问题。要简单一点归避掉时区的问题的话,你可以先做减法再做除法。

    然而,我想说的时,任何有关时间的计算,请使用标准库的数据结构与实现,避免依赖本地时间进行计算。自己土法实现的(比如除以 24,除以 60,除以 365 等等),99%都在某种场景下是错的。

    因为有关时间,你不但要考虑一般的时区、闰年这种特性,还有考虑闰秒、夏时制、非整数时区等这些稍微有点特殊的场景,还得考虑其它本地时间不连续等更为复杂的场景。这也就是为什么 Linux 系统里有个需要不定期更新的 tzdata 包的原因。
    infong
        25
    infong  
       2017-06-22 09:54:38 +08:00
    楼主的问题出在这里:
    var time1 = new Date("2017-6-1 7:00:00");
    var time2 = new Date("2017-6-1 9:00:00");

    这里定义的时间是有时区的,通过 time1.toString() 能看到时间是 "Thu Jun 01 2017 07:00:00 GMT+0800 (CST)"
    所以 time1 所对应的时间戳为 "Thu May 31 2017 23:00:00 GMT" 的时间戳

    猜猜下面输出是什么?
    var time3 = new Date('1970-1-1 00:00:00');
    console.log(time3/86400);
    amlun
        26
    amlun  
       2017-06-22 10:48:15 +08:00
    talk is cheap,show me the code!
    dinghua
        27
    dinghua  
       2017-06-22 11:37:12 +08:00
    我来解释解释;

    楼主看到结果一个是 17317.x , 一个是 17318.x, 就认为是两个时间不是在同 1 天。

    至于为什么,大家都提了,时区的问题。
    hicdn
        28
    hicdn  
       2017-06-22 17:39:41 +08:00
    @wl879

    var time1 = new Date("2017-6-1 7:00:00");
    var time2 = new Date("2017-6-1 9:00:00");

    console.log(time1, time1.getTime() / (60*60*24*1000))

    // 输出:Thu Jun 01 2017 07:00:00 GMT+0800 (CST) 17317.958333333332

    console.log(time2, time2.getTime() / (60*60*24*1000))

    // 输出:Thu Jun 01 2017 09:00:00 GMT+0800 (CST) 17318.041666666668

    你这个都是按照浏览器的 +8 时区 输出的本地时间,然而时间戳是按 0 时区算的。
    转换成 0 时区
    time1 2017.05.31 23:00 GMT+0000
    time2 2017.06.01 01:00 GMT+0000
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3010 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 13:38 PVG 21:38 LAX 05:38 JFK 08:38
    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