|
打算计算天数差,翻了翻网上的讨论,都用了循环。可是像M8这样的芯片,RAM倒是有几个,可速度就不是很快。用循环在PC上也许更合适。
想了想,反正每400年公历就经历一个循环,找出400年内的润平年数,就能用乘加的方法一次性算出相对某个400年周期的总天数,然后天数差就好算了。
从表中看出,公元0年、400年...2000年是闰年(当然历法中没规定0年),所以起始加一,然后再屏蔽掉一个闰年就能得到400年内的全部闰年数,再用年数乘365之后就得到本年之前经过的总天数了。之后确定本年内的天数,就得到包括当前日期在内的全部天数。这样就回避了循环。
用OCTAVE验证之后写了下面的程序。还附了一个计算annual date的程序,两个加起来比较好用。
程序里叫做qdt_time_t的类型不过是包含年月日整型变量的一个结构而已。- /*
- The days of the past years can be calculated by using the following formula:
- The year: 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
- MOD 400: 0 1 2 3 4 5 6 7 8 9 10 11 12
- Leap year: 0 1 0 0 0 1 0 0 0 1 0 0 0
- Days past: 0 366 365 365 365 366 365 365 365 366 365 365 365
- The sums: 0 366 731 1096 1461 1827 2192 2557 2922 3288 3653 4018 4383
- Formula: n = 1 + y*365 + fix((y-1)/4) - fix((y-1)/100) + fix((y-1)/400)
-
- Before 2012, we have 4383 + 146097 * 5 = 734868 days past. Where 146097 = 365 * 400 + 97 is a 400 years cycle.
- */
- uint32_t qdt_to_long_date(const qdt_time_t *time)
- {
- uint16_t year = time->year;
- /* The DOY means what day is today of the year. It is an annual date. */
- uint32_t days;
-
- if(year == 0){
- days = 0;
- }else{
- days = 1 + year * 365UL;
- year --;
- days += year/4 - year/100 + year/400;
- }
- /* Add the annual date at the final. */
- days += qdt_day_of_annual(time);
- return days;
- }
复制代码- uint16_t qdt_day_of_annual(const qdt_time_t *time)
- {
- /* Days accumulation table of an ordinary year. */
- static const uint16_t PROGMEM annual_table[] = {
- /* x 1 2 3 4 5 6 7 8 9 10 11 12 */
- 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
- };
- /* Use buffered values. */
- uint8_t month = time->month;
- uint8_t day = time->day;
-
- /* Using 16-bit unsigned integer accumulator. */
- uint16_t days = day + pgm_read_word(&annual_table[month]);
- /* Append one day in leap year. */
- if((month > 2) && qdt_is_leap_year(time)){
- days += 1;
- }
- return days;
- }
复制代码- uint8_t qdt_is_leap_year(const qdt_time_t *time)
- {
- /* For every 400 years, it's transmigrated. */
- uint16_t year = time->year % 400;
-
- return ((year == 0) || ((year % 4 == 0) && (year % 100 != 0)));
- }
复制代码 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|