表示法中,y = 2016,m = 8(取值0-11), d = 16 (取值0-30)
闰年
正常的闰年公式为
isLeapyear = year % 400 == 0 || year % 100 != 0 && year % 4 == 0
1700年以前的日期是非常混乱的,中间有多数日历变更,有多个年份都不是365、366天。
我们一般处理好1900~2100之间的年份就好了。这其间(不包括1900、2100)闰年可以简化为4的整数倍。
isLeapyear = year % 4 == 0
从天数求对应年份
这个公式很不错
year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
同样只考虑(1900,2100)之间可以简化为
year = 1900 + 4 * days / (365*4 + 1)
反向公式,从年份加年内的天求总从1900-1-1以后的天数。
day = yday + (year - 1900) * 365 - (year - 1900)/4
求年内的第多少天
知道年月日求第多少天,一般是查月份日期表ydayOfmonth, 这个表一般是平年闰年各一份。
yday = ydayOfMonth[isLeapyear][m] + d
其实如果对日历进行一些分析,我们也可以用一个不复杂的公式代替。
我们注意3-7月和8-12月每月天数一致都是31 30 31 30 31,就可以把一年分成三段计算
而3月是第59天或第60天开始,而8月从之后的153天开始,我们取小的数
if m > 7
yday = 212 + isLeapyear + (m - 7) * 30.5 + d
else if m > 2
yday = 59 + isLeapyear + (m - 2) * 30.5 + d
else
yday = m * 31 + d
30.5这个乘法可以改成整数, (m * 61) / 2, 合并中间的常数后得到
if m < 2
yday = m * 61 / 2 + d
else if m < 7
yday = (m * 61 + 1) / 2 + d - 3 + isLeapyear
else
yday = m * 61 / 2 + d - 2 + isLeapyear
如何算出月份
知道天数,如何算月份,这是最常见的难题,一般都需要循环。有
了上面的公式,我们知道可以根据天数计算月份。
if yday < 59 # 1-2月
month = yday / 31
else if yday < 212 # 3-7月
month = (day - 59) * 2 / 61 + 2;
else # 8 - 12月
month = (day - 212) * 2 / 61 + 7
闰秒
闰秒的计算似乎只能查表,好在大多数时候不需要考虑它。