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

从 1 月 31 号开始的一个月之后是哪天

  •  
  •   px920906 ·
    mdpx · 2020-08-30 19:14:04 +08:00 · 5924 次点击
    这是一个创建于 1551 天前的主题,其中的信息可能已经有所发展或是发生改变。

    2 月 28(29)号还是 3 月 3(2)号?

    google 了下好像是支持前者的比较多,但是这样的话,平年 1 月 28~31 四天开始的一个月之后都是 2 月 28 号,那如果一个人在后 3 天购买一个月有效期的产品不是亏了么,实际遇到这种情况会特殊处理吗?

    dayjs 的逻辑也是前者

    dayjs('2020/01/31').add(1,'month').toDate()
    // Sat Feb 29 2020 00:00:00 GMT+0800 (中国标准时间)
    

    如果用原生 js 的 setMonth 直接加一个月的话是后者

    var d = new Date('2020/01/31')
    d.setMonth(d.getMonth() + 1)
    // 1583107200000
    d
    // Mon Mar 02 2020 08:00:00 GMT+0800 (中国标准时间)
    

    以及各位看看中英文关键字分别得到的搜索结果,emmmm……

    批注 2020-08-30 182916.png

    批注 2020-08-30 182949.png

    26 条回复    2020-09-02 00:37:39 +08:00
    lmoon
        1
    lmoon  
       2020-08-30 19:17:21 +08:00 via Android   ❤️ 1
    一个月倾向于前者,31 天倾向于后者,你没发现现在有些会员不写一个月写 31 天吗?
    realpg
        2
    realpg  
       2020-08-30 19:31:48 +08:00   ❤️ 3
    收费性的业务需要,一般以付费方不吃亏,收费方多让点为主。
    winterbells
        3
    winterbells  
       2020-08-30 20:26:14 +08:00 via Android
    会员基本都是 31 天吧
    除了年付,有的写一个自然年
    jousca
        4
    jousca  
       2020-08-30 20:32:33 +08:00   ❤️ 1
    一般情况下考虑下个自然月终止。

    比如遇到 2 月这种,1 月 31 日续费,有效期直接到 3 月 1 日结束,规避闰年和平年问题。 也顺便规避大小月份问题。比如 2 月 28 日续费 1 个月,有效期到 4 月 1 日。 6 月 30 日续费,有效期到 8 月 1 日。给付费方一点优惠。
    wxsm
        5
    wxsm  
       2020-08-30 20:34:48 +08:00
    Date.setMonth:

    > The current day of month will have an impact on the behaviour of this method. Conceptually it will add the number of days given by the current day of the month to the 1st day of the new month specified as the parameter, to return the new date. For example, if the current value is 31st August 2016, calling setMonth with a value of 1 will return 2nd March 2016. This is because in 2016 February had 29 days.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth

    简单来说,dayjs 的逻辑才是正确的。setMonth 做了一些不该做的事情。别觉得奇怪,这就是 javascript,奇怪的不只这一处。
    kaiki
        6
    kaiki  
       2020-08-30 20:39:37 +08:00
    腾讯的会员业务是按照 31 天算。
    阿里云的服务器是按照日期算,大于则取最大日期,如 1 月 31 号购买一个月的服务器,到期是 2 月 28 或者 29 号,好像是这样的。
    qinxi
        7
    qinxi  
       2020-08-30 21:13:09 +08:00
    看了微博视频的我表示. 可以是 3.4 3.6 5.1 6.4 10.1.12.9 等等等 都是.哈哈哈哈哈哈哈哈
    littlewing
        8
    littlewing  
       2020-08-30 21:15:40 +08:00
    1 个月之后 是 2 月最后一天
    30 或者 31 天之后,按实际天数算
    Mutoo
        9
    Mutoo  
       2020-08-30 21:26:26 +08:00
    取决于你的业务怎么定义:「下一个(自然)月」、「下一个月的今天」
    可以配合 startOfMonth() / endOfMonth() 之类的函数使用。
    zhizunzz
        10
    zhizunzz  
       2020-08-30 21:33:03 +08:00
    从明日零点开始计算, 今天剩余的几小时算是无尖不商的"尖", 一个月按 30 天算, 半年按 180 算, 一年就到明年今天
    yidinghe
        11
    yidinghe  
       2020-08-30 22:17:15 +08:00
    所以不要以月为单位嘛,就说 30 天就好了。
    gaius
        12
    gaius  
       2020-08-31 00:40:38 +08:00 via Android
    一般 addMonth(1)这种 api 都是 2 月最后一天,看业务了
    anguiao
        13
    anguiao  
       2020-08-31 00:44:40 +08:00 via Android
    忘了是哪个服务了,我买的时候是 30 号,结果到了第二年 2 月,就变成 28 号到期了。虽然没多少钱,但是感觉还是很不爽的。
    JustPisces
        14
    JustPisces  
       2020-08-31 00:58:00 +08:00
    我个人倾向于按天数算的,一个月给 31 天,一年按 366 天计算
    hanqian
        15
    hanqian  
       2020-08-31 02:50:39 +08:00 via iPhone   ❤️ 1
    说个不相关的,从楼主最后截图能看出 Google 中文搜索被污染的有多严重
    mytharcher
        16
    mytharcher  
       2020-08-31 03:30:34 +08:00 via Android
    这里面隐含了两个问题,一个是:什么叫“一个月之后”?是简单的 month + 1 ?还是以当前月份的天数为一个月为增量?甚至是以全年平均月份天数去整为增量?

    第二个是:当前虽然标定在了一月的最后一天,但说的一个月之后是否代表了“下个月最后一天”?即是使用了倒数的方向。

    这两个问题没有合理的定义的话,就没法给出答案了。
    baobao1270
        17
    baobao1270  
       2020-08-31 05:06:32 +08:00
    要么每个月 30 天算,很多云服务器都是这么算的,会计上也是这样算的
    要么按“一个月的第几天”算并向下取整(即 1/5+1mo=2/5 ; 1/31+1mo=2/28 ),这个适合按月包的服务
    要么一个一个月的算,1/31-1/31 一个周期,第二个周期是 2/1-2/28,第三个是 3/1-3/31,依次类推
    lihongming
        18
    lihongming  
       2020-08-31 05:12:07 +08:00 via iPhone
    按月算,自然有大小月的问题,一般是指下个月的这一天,没有的话就到最后一天。

    还有按自然月算的,更坑。比如 AWS 的某些服务,月底开始用也得收一个月的钱。
    danhahaha
        19
    danhahaha  
       2020-08-31 08:16:42 +08:00
    @hanqian 导致有些问题不得不用英文搜索,中文搜索有时候搜出几页内容牧场,不知道是 Google 懒于管理还是中文用的少
    cco
        20
    cco  
       2020-08-31 09:03:18 +08:00
    目前就我订阅的东西来看,都是按照自然月算的。全年算下来也就差 1 天,懒得纠结。除非按天算的,一天的成本大于 10 块( vps 之类的除外)。
    crclz
        21
    crclz  
       2020-08-31 09:31:17 +08:00
    用 TimeDelta ( TimeSpan )算,然后再给客户补足 24h
    passerbytiny
        22
    passerbytiny  
       2020-08-31 10:23:14 +08:00 via Android
    首先,这是现实问题,而不是技术问题——不管是任何逻辑,任何编码语言,代码都能给你实现。

    然后现实上其实也没那么复杂,就是一个周期选择的问题——固定天还是自然月。固定天就不用说了,固定 30/31 天为一个周期。自然月的话就看商家的良心(其实跟良心无关就是随便选的)了,1-28 号起始的就不用管了,29-31 号起始的有三种选择:
    一,那几天关门大吉;
    二,那几天白送,按照下月一号开始计周期(这是我认为的最优解);
    三,自动适配,若该月有这一日就是这一日,否则就是月末那一日(例 1:1/31 > 2/28 > 3/31/4/30 > 5/31 )(例 2:1/29 > 2/28 > 3/29 >……> 2/29 >……)

    (若发生了 1/31 > 2/28 > 3/28 > 4/28 的情况,那不是第四种,是技术不过关代码有 bug )。
    Jinnn
        23
    Jinnn  
       2020-08-31 11:17:03 +08:00
    直接给 31 天, 用户开心, 你维护的也舒服
    daozhihun
        24
    daozhihun  
       2020-08-31 11:25:22 +08:00
    如果是口语,一般是指自然月吧,也就是 2/28
    但是如果涉及到付费之类的,同意楼上的看法,直接按 31 天算比较合适
    MengiNo
        25
    MengiNo  
       2020-08-31 18:04:03 +08:00
    @hanqian 个人认为这个地方是楼主的关键词有误, "1 月 31 号开始一个月" 无论怎么说也不像是一个完整的中文表达,如果不看上下文,单放这么一个截图 虽然答案很奇怪,但是我相信大部分人会觉得 搜索关键词更奇怪。

    我用比较白话的表达 "1 月 31 号后一个月是几号" 作为关键词搜索 谷歌直接出的结果是 Wednesday, March 3, 2021 。 下面第一条结果链接是本文,第二条结果是百度知道,第三条之后是知乎 掘金 开源中国等讨论 等代码相关的结果,混合着一些 关于预产期的结果,不知道是不是我登着谷歌账户的缘故。
    jousca
        26
    jousca  
       2020-09-02 00:37:39 +08:00
    @hanqian 我专门用了插件来过滤 google 中文结果里的垃圾站
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1097 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:38 · PVG 06:38 · LAX 14:38 · JFK 17:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.