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

30 篇文章 0 订阅

转载于:http://blog.csdn.net/poechant/article/details/7425604

 

或许一些人,认为自己会调用Windows API、Java SDK的API等等能将毫秒数转换为精确的时间就可以了。但这里讨论的不是如何运用某种语言的某个框架的API,MFC的COleDateTime、Java中的涉及Date的相关接口、JavaScript中的涉及Date的相关接口的内部实现,可能就是本文的类似内容。要实现Nginx等一些高性能server-side的软件,必须要了解如何从根本做起,这不是重新造轮子。

下文中会用到一些公式,比如: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; /* 星期 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值