偶尔发现Windows Mobile连一些标准的C语言库函数都没有实现,而这些函数的在头文件中的声明却是有的,实在有些不方便,上网一搜索,才知道原来Windows CE也没实现,而Windows Mobile这方面照搬了Windows CE的,如果真要用这些函数,只能自己来写了,我写了这几个:gmtime,localtime,mktime,strftime,其中用到了Variant Time这个类型,它实质上是个浮点数,浮点数就意味着有时候不太精确,我实践下来确实发觉有时候会有1秒钟的偏差,在计算time_t的时候,不过暂时懒得去管它了。使用方法很简单,把代码复制一份,保存到一个叫“TimeFunctions.cpp”的文件中去,然后在你的project中添加这个文件即可。
#include <time.h>
#include <windows.h>
static BOOL IsLeapYear(WORD nYear)
{
return !(nYear % 4) && (nYear % 100) || !(nYear % 400);
}
static int DaysFromJan1st(WORD wYear, WORD wMonth)
{
static WORD monthday[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
return monthday[wMonth - 1] + (IsLeapYear(wYear) && wMonth > 2 ? 1 : 0);
}
static tm* GetTmByVariant(DOUBLE dTime)
{
SYSTEMTIME stResult;
VariantTimeToSystemTime(dTime, &stResult);
static tm s_tm;
s_tm.tm_sec = stResult.wSecond;
s_tm.tm_min = stResult.wMinute;
s_tm.tm_hour = stResult.wHour;
s_tm.tm_mday = stResult.wDay;
s_tm.tm_mon = stResult.wMonth-1;
s_tm.tm_year = stResult.wYear-1900;
s_tm.tm_wday = stResult.wDayOfWeek;
s_tm.tm_yday = DaysFromJan1st(stResult.wYear, stResult.wMonth);
s_tm.tm_isdst = 0;
return &s_tm;
}
const DOUBLE VT_SECOND_1970 = 2209161600.0;
const DOUBLE SECONDS_IN_ONE_DAY = 86400;
tm* __cdecl gmtime(const time_t* pTT)
{
return GetTmByVariant((VT_SECOND_1970 + (*pTT))/SECONDS_IN_ONE_DAY);
}
tm* __cdecl localtime(const time_t* pTT)
{
TIME_ZONE_INFORMATION tz;
GetTimeZoneInformation(&tz);
return GetTmByVariant((VT_SECOND_1970 + (*pTT) - tz.Bias*60)/SECONDS_IN_ONE_DAY);
}
time_t __cdecl mktime(tm* pTM)
{
SYSTEMTIME stToConvert = {
pTM->tm_year+1900,
pTM->tm_mon+1,
pTM->tm_wday,
pTM->tm_mday,
pTM->tm_hour,
pTM->tm_min,
pTM->tm_sec,
0};
DOUBLE dToCal;
SystemTimeToVariantTime(&stToConvert, &dToCal);
return (time_t)(dToCal*SECONDS_IN_ONE_DAY - VT_SECOND_1970);
}
static void strfmt(char *str, const char *fmt, )
{
int ival, ilen;
char *sval;
static int pow[5] = { 1, 10, 100, 1000, 10000 };
va_list vp;
va_start(vp, fmt);
while (*fmt)
{
if (*fmt++ == '%')
{
ilen = *fmt++ - '0';
if (ilen == 0) // zero means string arg
{
sval = va_arg(vp, char*);
while (*sval)
*str++ = *sval++;
}
else // always leading zeros
{
ival = va_arg(vp, int);
while (ilen)
{
ival %= pow[ilen--];
*str++ = (char)('0' + ival / pow[ilen]);
}
}
}
else *str++ = fmt[-1];
}
*str = '\0';
va_end(vp);
}
#define DAYSPERWEEK 7
size_t __cdecl strftime(char* pTimeStr, size_t stStrLen, const char* pFmt, const tm* pTM)
{
static char *aday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static char *day[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
static char *amonth[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static char *month[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int w;
char *p, *q, *r;
static char buf[26];
p = pTimeStr;
q = pTimeStr + stStrLen - 1;
while ((*pFmt != '\0'))
{
if (*pFmt++ == '%')
{
r = buf;
switch (*pFmt++)
{
case '%' :
r = "%";
break;
case 'a' :
r = aday[pTM->tm_wday];
break;
case 'A' :
r = day[pTM->tm_wday];
break;
case 'b' :
r = amonth[pTM->tm_mon];
break;
case 'B' :
r = month[pTM->tm_mon];
break;
case 'c' :
strfmt(r, "%0 %0 %2 %2:%2:%2 %4",
aday[pTM->tm_wday], amonth[pTM->tm_mon],
pTM->tm_mday,pTM->tm_hour, pTM->tm_min,
pTM->tm_sec, pTM->tm_year+1900);
break;
case 'd' :
strfmt(r,"%2",pTM->tm_mday);
break;
case 'H' :
strfmt(r,"%2",pTM->tm_hour);
break;
case 'I' :
strfmt(r,"%2",(pTM->tm_hour%12)?pTM->tm_hour%12:12);
break;
case 'j' :
strfmt(r,"%3",pTM->tm_yday+1);
break;
case 'm' :
strfmt(r,"%2",pTM->tm_mon+1);
break;
case 'M' :
strfmt(r,"%2",pTM->tm_min);
break;
case 'p' :
r = (pTM->tm_hour>11)?"PM":"AM";
break;
case 'S' :
strfmt(r,"%2",pTM->tm_sec);
break;
case 'U' :
w = pTM->tm_yday/7;
if (pTM->tm_yday%7 > pTM->tm_wday)
w++;
strfmt(r, "%2", w);
break;
case 'W' :
w = (pTM->tm_yday + DAYSPERWEEK -
(pTM->tm_wday ?
(pTM->tm_wday - 1) :
(DAYSPERWEEK - 1))) / DAYSPERWEEK;
strfmt(r, "%2", w);
break;
case 'w' :
strfmt(r,"%1",pTM->tm_wday);
break;
case 'x' :
strfmt(r, "%2/%2/%2", pTM->tm_mon + 1,
pTM->tm_mday, pTM->tm_year+1900);
break;
case 'X' :
strfmt(r, "%2:%2:%2", pTM->tm_hour,
pTM->tm_min, pTM->tm_sec);
break;
case 'y' :
strfmt(r,"%2",pTM->tm_year%100);
break;
case 'Y' :
strfmt(r,"%4",pTM->tm_year+1900);
break;
case 'Z' :
// r = (pTM->tm_isdst && tz_name[1][0])?tz_name[1]:tz_name[0];
break;
default:
buf[0] = '%'; // reconstruct the format
buf[1] = pFmt[-1];
buf[2] = '\0';
if (buf[1] == 0)
pFmt--; // back up if at end of string
}
while (*r)
{
if (p == q)
{
*q = '\0';
return 0;
}
*p++ = *r++;
}
}
else
{
if (p == q)
{
*q = '\0';
return 0;
}
*p++ = pFmt[-1];
}
}
*p = '\0';
return p - pTimeStr;
}