帮Windows Mobile实现gmtime,localtime,mktime和strftime

帮Windows Mobile实现gmtime,localtime,mktime和strftime

偶尔发现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)
                {
                    
* =   ' \0 ' ;
                    
return   0 ;
                }
                
* p ++   =   * r ++ ;
            }
        }
        
else
        {
            
if  (p  ==  q)
            {
                
* =   ' \0 ' ;
                
return   0 ;
            }
            
* p ++   =  pFmt[ - 1 ];
        }
    }
    
* =   ' \0 ' ;
    
return  p  -  pTimeStr;
}


你可能感兴趣的:(帮Windows Mobile实现gmtime,localtime,mktime和strftime)