ctime, mktime 64位版本
来源:互联网 发布:晓风网贷软件 编辑:程序博客网 时间:2024/04/29 18:33
背景介绍
====
进来因为移植万年历, 需要比较和计算1970之前和之后的时间,比如1900-2100。javascript 中Date.UTC() 对于小于
1970 的日期返回负值,对大的日期也支持,很好用。于是想如何在C中做。
我试图改造过 ADOdb Date Library, part of the ADOdb abstraction library
Download: http://phplens.com/phpeverywhere/,把PHP翻译为C, 但是它写的啰嗦, 很是麻烦, 还有性能问题。
最后想到可以参考标准库, 设计决策, 不要使用负值time_t, 处理起来麻烦;规定1900为0起点,-1表示出错。
全文如下,FYI:
/*time64.c -- 64 bit version of time.cauthor: ludiref P.J. PLAUCER "the standard C library.pdf"doc:time_t -- unsigned int -- [1900,2036]unix -- 1970.01.01 00:00:00 -- (70*365+17)*86400 seconds passed since 1900._I64_MAX = 9223372036854775807 -- enough for big bang time--15 billion years = 47304 * 10^13 seconds.*/#include <stdint.h>#include <limits.h>#include <stdio.h>typedef struct datetime{int second; /*seconds after the minute [0,61]*/int minute; /*minutes after the hour [0,59]*/int hour; /*hours since midnight [0,23]*/int mday; /*day of the month [1,31]*/int mon; /*months since January [0,11]*/int year; /*years since _1900_*/int wday; /*days since Sunday [0,6]*/int yday; /*days since January 1 [0,365]*/}datetime_t;typedef int64_t date_t;#define _TBIAS ((date_t)(70*365+17)*86400)#define WDAY 1static const short lmos[] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};static const short mos[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};#define MONTAB(y) (y & 03 || y == 0 ? mos : lmos)int isLeapYear(int year){/*四年一闰,百年不闰,四百年再闰*/return (year%4==0&&year%100!=0)||year%400==0;}void test_leap(){int start = 1901, end = 50050;int i, sum = 0, day;for(i = start; i <= end; ++i){if(isLeapYear(i))++sum;}end = end - start;day = end/4 - end/100 + (1900+end)/400 - 1900/400;printf("real %d, esti %d\n", sum, day);}int Daysto(int year, int mon){/*compute extra days to start of month*/int days, end;/*correct for leap year: 1801-*/if(0 < year){end = year - 1;days = end/4 - end/100 + (1900+end)/400 - 1900/400;}else if(year <= -4){days = 1 + (4-year)/4;}else{days = 0;}return days + MONTAB(year)[mon];}datetime_t Ttotm( date_t secarg){/*convert scalar time to datetime*/int year, mon;date_t days, i;date_t secs;datetime_t dt;const short *pm;secs = secarg + _TBIAS;days = secs/86400;dt.wday = (days + WDAY)%7;for(year = days/365; days < (i = Daysto(year, 0) + 365*year);)--year;days -= i;dt.year = year;dt.yday = days;pm = MONTAB(year);for(mon = 12; days < pm[--mon]; );dt.mon = mon;dt.mday = days - pm[mon] + 1;secs %= 86400;dt.hour = secs/3600;secs %= 3600;dt.minute = secs/60;dt.second = secs%60;return dt;}date_t tmtoT(datetime_t *t){/*convert time structure to scalar time*/long double dsecs;int mon, year, ymon;date_t secs;ymon = t->mon/12;mon = t->mon - ymon*12;if(mon < 0)mon += 12, --ymon;if(ymon < 0 && t->year < INT_MIN - ymon || 0 < ymon && INT_MAX - ymon < t->year) return (date_t)-1;year = t->year + ymon;dsecs = 86400.0 * (Daysto(year, mon) - 1)+ 31536000.0 * year + 86400.0 * t->mday;dsecs += 3600.0 * t->hour + 60.0 * t->minute + (double)t->second;if(dsecs < 0.0)return (date_t)(-1);secs = (date_t)dsecs - _TBIAS;return secs;}int main(){test_leap();datetime_t dt = {.year = 1900 - 1900,.mon = 6 - 1,.mday = 18,.hour = 18,.minute = 48,.second = 0,};datetime_t d2 = {0};date_t t = tmtoT(&dt);d2 = Ttotm(t);/*you can compare with: var t = Date.UTC(3013,5,18, 18, 48,0)/1000; document.write(" t " + t);*/printf("t %I64d \n", t);printf("%d-%d-%d %02d:%02d:%02d\n", d2.year + 1900, d2.mon + 1, d2.mday, d2.hour, d2.minute, d2.second);}
- ctime, mktime 64位版本
- struct tm && ctime localtime mktime
- mktime timecore.cpp 40 ctime
- struct tm,time,localtime,mktime,ctime,gmtime,difftime,asctime,strftime
- c语言中的time ctime asctime gmtime localtime mktime
- C/C++时间函数time/localtime/mktime/ctime/strftime使用方法
- C/C++时间函数time/localtime/mktime/ctime/strftime使用方法
- 早期版本的mktime.c
- mktime
- mktime
- 四位字符串赋值CTime
- Linux常用C函数-asctime,ctime,getttimeofday,gmtime,localtime,mktime,settimeofday,time
- Linux常用C函数-asctime,ctime,getttimeofday,gmtime,localtime,mktime,settimeofday,time
- 32位/64位WIN2003各版本
- STK11 32位和64位版本
- CTime
- CTime
- CTime
- 前端技术
- 关闭http
- jQuery选择器之过滤选择器之基础过滤选择器
- PE文件格式
- Python中调用dll
- ctime, mktime 64位版本
- 友元(friend)--初学篇
- 最长有序子序列—动态规划算法
- JSP常用内置对象的常用方法总结
- UIBarButtonItem-添加自定义Left或者Right按钮
- IGT笔试
- 1-11排序
- VC++能用的,遍历文件夹及子文件夹文件的代码
- 随笔(三)