long rtt_mktime(DATE_TIME time, long timezone /*= 8*/)
{
long res;
// 1..12 -> 11,12,1..10, Puts Feb last since it has leap day
if (time.month <= 2)
{
time.month += 10;
time.year -= 1;
}
else
{
time.month -= 2;
}
/**//*
// Calculate how much days from 1970 to today
res = 59; //31@0001-January and 28@0001-February
res += (time.year - 1) * 365; //at least 365 days one year
res += time.year / 4 - time.year / 100 + time.year / 400; //leap years from 0001
res += 367 * time.month / 12 - 30; //days from March(0.5/7<=slope<0.5/5)
res += time.day - 1; //days
res -= 719162; //days from 0001-1-1 to 1970-1-1
// Calculate how much seconds
res = ( (res * 24 + time.hour) * 60 + time.minute) * 60 + time.second;
*/
/***
res = (long)(time.year/4 - time.year/100 + time.year/400) +
367*time.month/12 + time.day +
time.year*365 - 719499;
res = ((res*24 + time.hour // now have hours
)*60 + time.minute // now have minutes
)*60 + time.second; // finally seconds
//*/
res -= timezone * 60 * 60;
return res;
}
int rtt_isleap(unsigned short year)
{
return ((year%4==0)&&(year%100!=0)||(year%400==0));
}
void rtt_localtime(long res, DATE_TIME *time, long timezone /*= 8*/)
{
const int monthLengths[2][13] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366},
};
const int yearLengths[2] = { 365, 366 };
int year;
int month;
int minMonth;
int maxMonth;
int days;
int clock;
int isLeap;
res += timezone*60*60;
days = res / 86400;
clock = res % 86400;
if(clock < 0)
{
clock += 86400;
days -= 1;
}
/**/
// Calcaulate year, 11323=0x3A4FC880/86400; 13879=0x47798280/86400
/**
if(days >= 0)
{
year = days/366;
days -= year*365 + (year+1)/4 - (year+69)/100 + (year+369)/400;
for(time->year = year + 1970; ; time->year++)
{
isLeap = rtt_isleap(time->year);
if(days < yearLengths[isLeap])
{
break;
}
days -= yearLengths[isLeap];
}
}
else
{
year = days/366;
days -= year*365 + (year-2)/4 - (year-30)/100 + (year-30)/400;
for(time->year = year + 1970 - 1; ; time->year--)
{
isLeap = false;//rtt_isleap(time->year);
days += yearLengths[isLeap];
if(days >= 0)
{
break;
}
}
}
/**///
// compute month and day, use the half search save time
/**
minMonth = 0;
maxMonth = 12;
for(month = 5; month < 12 && month > 0; month = (minMonth + maxMonth) / 2)
{
// days between monthLengths[month]<=days
if(days < monthLengths[isLeap][month]) //too big
{
maxMonth = month;
}
else if(days >= monthLengths[isLeap][month + 1]) //too small
{
minMonth = month;
}
else //so it is
{
break;
}
}
days -= monthLengths[isLeap][month];
time->month = month + 1;
time->day = days + 1;
/**///
// Calcaulate hour minute and second
/**///
time->hour = clock / 3600; //3600s one hour
clock = clock % 3600;
time->minute = clock / 60; //60s one minute
time->second = clock % 60; //ms
}
/*========================================================================
* Function name : gmt_convert_local
* Description : 将格林尼治时间转换为本地时间
* Return type : bool
* Argument :
* : const char* gmt 格林尼治时间 20091105082121
* : char* local 20091105/162121
========================================================================*/
bool gmt_convert_local(const char* gmt, char* local)
{
if ( strlen(gmt) != 14 )
return false;
//格林尼治时间转换为本地时间
char year[5];
char month[3];
char day[3];
char hour[3];
char minute[3];
char second[3];
sscanf(gmt, "%4s%2s%2s%2s%2s%2s", year, month, day, hour, minute, second);
DATE_TIME utc_time;
DATE_TIME local_time;
utc_time.year = atoi(year);
utc_time.month = atoi(month);
utc_time.day = atoi(day);
utc_time.hour = atoi(hour);
utc_time.minute = atoi(minute);
utc_time.second = atoi(second);
long time_second = rtt_mktime(utc_time, 0);//utc时间, 0 时区
rtt_localtime(time_second, &local_time, 8);
sprintf(local, "%04d%02d%02d/%02d%02d%02d", local_time.year, local_time.month, local_time.day,
local_time.hour, local_time.minute, local_time.second);
return true;
}