• 根据毫秒数计算出当前的“年/月/日/时/分/秒/星期”并不是件容易的事


    • 作者:钟超
    • 博客:柳大·PoechantBlog.CSDN.net
    • 日期:April 4th, 2012

    下文中会用到一些公式,比如:empirical formulaGauss' formula等。主要思想取自 Nginx 的时间管理机制中。

    1 毫秒、秒、分、时

    如果已知毫秒数为:

    unsigned int msec_total;
    

    那么秒数和余毫秒数为:

    unsigned int sec_total = msec_total /  1000;
    unsigned int msec = msec_total % 1000; /* What we want */
    

    分钟数和余秒数为:

    unsigned int min_total = sec_total / 60;
    unsigned int sec = sec_total % 60;
    

    小时数和余分钟数为:

    unsigned int hour_total = min_total / 60;
    unsigned int min = min_total % 60;
    

    余小时数为:

    unsigned int hour = hour_total % 24;
    

    剩下的内容非常重要。

    2 总天数

    unsigned int day_total = hour_total / 24;
    day_total = day_total - (31 + 28) + 719527; /* days since March 1, 1 BC */
    

    3 年数

    什么是闰年?有如下几类:

    • 能被4整除,但不能被100整除;
    • 能被400整除。

    所以总年数是:

    /* 总年数 */
    year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
    

    还要继续知道整年的余天:

    /* yday是整年的余天 */
    yday = days - (365 * year + year / 4 - year / 100 + year / 400);
    
    /* 如果余天小于0,说明年数应该减一 */
    if (yday < 0) {
        /* 可以被4整除,且不可以被100整除,且可以被400整除 */
        leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
        /* 加当年的年数补差值 */
        yday = 365 + leap + yday;
        year--;
    }
    

    具体的解释看注释。

    4 月份和日期

    转载请注明来自柳大的CSDN博客:Blog.CSDN.net

    这里用到empirical formulaGauss' formula

    /*
     * The empirical formula that maps "yday" to month.
     * There are at least 10 variants, some of them are:
     *     mon = (yday + 31) * 15 / 459
     *     mon = (yday + 31) * 17 / 520
     *     mon = (yday + 31) * 20 / 612
     */
    
    /* 30.6 为平均每月天数 */
    mon = (yday + 31) * 10 / 306;
    
    /* the Gauss' formula that evaluates days before the month */
    
    mday = yday - (367 * mon / 12 - 30) + 1;
    
    if (yday >= 306) {
    
        year++;
        mon -= 10;
    
        /*
         * there is no "yday" in Win32 SYSTEMTIME
         *
         * yday -= 306;
         */
    
    } else {
    
        mon += 2;
    
        /*
         * there is no "yday" in Win32 SYSTEMTIME
         *
         * yday += 31 + 28 + leap;
         */
    }
    

    5 星期

    wday = (4 + days) % 7; /* 今儿是星期几?注意,1970年1年1日为星期四 */
    

    6 整理日期

    msec; /* 毫秒 */
    sec;  /* 秒 */
    min;  /* 分 */
    hour; /* 小时 */
    mday; /* 日 */
    mon;  /* 月 */
    year; /* 年 */
    wday; /* 星期 */
    

    7 后记

    7.1 将闰秒写入计算机的时间计算方法?

    闰秒是人为加入的,计算机中如何表示?什么时候插入闰秒,是由人来决定的,只不过原因是可探究的,但依然无法用公式或程序来计算。

    7.2 谁决定是否加入闰秒?

    是否加入闰秒由位于巴黎的国际地球自转和参考座标系统服务决定,在格里历的每年的6月或12月的最后一天的最后一分钟进行跳秒或不跳秒,也就是说每年的这两个一分钟并不就是等于60秒,而是在60秒上下变化。

    7.3 停止闰秒的表决(以下摘自中文维基)

    全球定位系统服务界面委员会在得克萨斯州沃斯堡举行的第47届会议中宣布,他们已经邮寄出停止闰秒的表决案。这项表决案的计划是[1]:

    • 2008年4月:国际电信联盟的工作小组将递交给研究小组关于劝说停止闰秒的7A建议项目。
    • 在2008年,研究小组将通过经由邮件让各会员国投票表决该议案。
    • 2011年:如果70%以上的会员国同意,国际电信会议将批准该建议案。
    • 2013年:如果70%以上的会员国投票废止闰秒,闰秒将停止使用,并且世界时(UTC)将成为连续的时间刻度尺。

    -

    转载请注明来自柳大的CSDN博客:Blog.CSDN.net

    -

  • 相关阅读:
    图匹配板子
    线性基
    Berlekamp-Massey algorithm
    组合/概率/形式幂级数/多项式/集合幂级数的题
    费用流 Dijkstra 原始对偶方法(primal-dual method)
    UVA-12304
    二项式系数
    卡特兰数
    多项式模板
    工具
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/3763259.html
Copyright © 2020-2023  润新知