http://bbs./thread-4131610-1-1.html 发表于 2014-03-17 01:35:39 |只看该作者 最近觉得写这个还蛮好玩的,就试着写了一个,并且和UTC的系统自带转换比较了一下,在32位范围(到2038年)没有发现问题。 可以优化的地方还蛮多,比如一些循环的地方(其实主要就是算年份有多少天啦)可以查表,对于月份也可以查表,这些都是可以优化的地方。 本来开始是直接天数除以365.2425(UTC的值),但是发现这样不行,在一些特定的天数会有误差,最后不得不循环数天数了 = = 有兴趣的可以做一些优化,代码如下: #include <stdio.h> #include <string.h> #include <time.h> #include <math.h> #define DAY_SEC (24*60*60) #define UTC_YEAR_SEC (31556926) struct my_tm { int year; int month; int day; int hour; int minute; int second; int weekdays; }; static int isleap(int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } int get_yeardays(int year) { if (isleap(year)) return 366; return 365; } void split_year_day_std(int days, int *year, int *day) { int curr_day = get_yeardays(*year = 1970); while (days >= curr_day) { days -= curr_day; *year += 1; curr_day = get_yeardays(*year); } *day = days; } void get_monthday(int day, int is_leap, struct my_tm *tm) { int i, mons[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (is_leap) mons[1] += 1; for (i = 0; i < 12; ++i) { if (day < mons[i]) { tm->month = i+1; tm->day = day+1; return; } day -= mons[i]; } } void get_subtime(int sec_in_day, struct my_tm *tm) { tm->hour = sec_in_day/(60*60); tm->minute = sec_in_day%(60*60)/60; tm->second = sec_in_day%60; } struct my_tm get_time(unsigned time) { struct my_tm tm; split_year_day_std(time/DAY_SEC, &tm.year, &tm.day); get_monthday(tm.day, isleap(tm.year), &tm); get_subtime(time % DAY_SEC, &tm); return tm; } void my_strftime(char buff[32], struct my_tm tm) { sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); } void sys_strftime(char buff[32], time_t t) { strftime(buff, 32, "%Y-%m-%d %H:%M:%S", gmtime(&t)); } int main(void) { unsigned t; for (t = 0; t < (1<<31); t += DAY_SEC) { char buff1[32], buff2[32]; my_strftime(buff1, get_time(t)); sys_strftime(buff2, (time_t)t); if (strncmp(buff1, buff2, 32)) { printf("%u\n %s\n %s\n", t, buff1, buff2); } } return 0; #if 0 /* command line or batch process */ while (scanf("%d", &t) != EOF) { char buff1[32]; my_strftime(buff1, get_time(t)); printf("%s\n", buff1); } return 0; #endif }
|
|