Unix时间戳(Unix timestamp), 定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
//Unix时间戳从1970-1-1 (星期4) 0:0:0 开始计算
#define IsLeapYear(wy) ((wy%400 == 0) || ((wy%4==0) && (wy%100)))
#define DAYSECONDS (24*60*60I64)
#define TIMESTAMP_BEGIN_YEAR 1970
#define TIMESTAMP_BEGIN_WEEK 4
typedef LONGLONG int64;
//返回某一年的总天数
inline int GetYearDays(int wYear)
{
return IsLeapYear(wYear)? 366:365;
}
#define GetYearDaysTick(wYear) (GetYearDays(wYear) * DAYSECONDS)
//返回某月的总天数
inline int GeMonthDays(int wYear, int wMonth)
{
static const int mothDays[]=
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
return (mothDays[wMonth - 1] + ((wMonth == 2 && IsLeapYear(wYear))? 1:0));
}
#define GeMonthDaysTick(wYear, wMonth) (GeMonthDays(wYear, wMonth) * DAYSECONDS)
//Unix时间戳转换为本地时间
//iUnixTimeStamp UNIX timestamp
//fZoneHours 时区时间 0=UTC 8=Begin etc.
//tmLocal 本地时间
BOOL ConvUnixTimestamp2SystemTime(
__in int64 iUnixTimeStamp, __in double fZoneHours, __out SYSTEMTIME &tmLocal)
{
int wYear=TIMESTAMP_BEGIN_YEAR, wMonth=1, wDay=1;
int64 iTotalTick = iUnixTimeStamp;
iTotalTick += (int64)(fZoneHours * 60*60); //+时区时
//计算星期 (Sunday = 0, Monday = 1, and so on)
int wWeek = TIMESTAMP_BEGIN_WEEK;
{
int iWeekOff = (int)((iTotalTick/DAYSECONDS) % 7);
if(iTotalTick < 0) { iWeekOff += 6; } //往前推算
wWeek = (wWeek + iWeekOff) % 7;
}
//负数时计算出一个起始为正值的年份
while(iTotalTick < 0)
{
wYear--;
iTotalTick += GetYearDaysTick(wYear);
}
//按剩余天数推算年
while(1)
{
int64 iYearDaysTick = GetYearDaysTick(wYear);
if(iTotalTick >= iYearDaysTick)
{
iTotalTick -= iYearDaysTick;
wYear++;;
}
else
{
break;
}
}
//月
while(1)
{
int64 iMonthDaysTick = GeMonthDaysTick(wYear, wMonth);
if(iTotalTick >= iMonthDaysTick)
{
iTotalTick -= iMonthDaysTick;
wMonth++;
}
else
{
break;
}
}
//日
{
wDay += (int)(iTotalTick / DAYSECONDS);
iTotalTick -= (wDay - 1)*DAYSECONDS;
}
//时分秒
int LeftTime = (int)(iTotalTick % DAYSECONDS); //剩余秒
int wHour = LeftTime / (60*60);
LeftTime -= wHour * (60*60);
int wMinute = LeftTime / 60;
LeftTime -= wMinute * 60;
int wSecond = LeftTime;
//结果赋值
memset(&tmLocal, 0, sizeof(tmLocal));
tmLocal.wYear = wYear;
tmLocal.wMonth = wMonth;
tmLocal.wDayOfWeek = wWeek;
tmLocal.wDay = wDay;
tmLocal.wHour = wHour;
tmLocal.wMinute = wMinute;
tmLocal.wSecond = wSecond;
return TRUE;
}
//本地时间转换为Unix时间戳
//tmLocal 本地时钟
//fZoneHours 时区时间 0=UTC +8=北京 ect
//返回Unix时间戳
int64 ConvSystemTime2UnixTimestamp(__in SYSTEMTIME &tmLocal, __in double fZoneHours)
{
//总天数
int64 iTotalDays = 0;
//年
{
int wYear;
//负数?
for(wYear=TIMESTAMP_BEGIN_YEAR-1; wYear>=tmLocal.wYear; wYear--)
{
iTotalDays -= GetYearDays(wYear);
}
//正数?
for(wYear=TIMESTAMP_BEGIN_YEAR; wYear<tmLocal.wYear; wYear++)
{
iTotalDays += GetYearDays(wYear);
}
}
//月
{
for(int wMonth=1; wMonth<tmLocal.wMonth; wMonth++)
{
iTotalDays += GeMonthDays(tmLocal.wYear, wMonth);
}
}
//日
{
iTotalDays += tmLocal.wDay-1;
}
//转换成秒
int64 iUnixTimeStamp = 0;
iUnixTimeStamp += iTotalDays * DAYSECONDS;
iUnixTimeStamp += tmLocal.wHour * (60 * 60);
iUnixTimeStamp += tmLocal.wMinute * 60;
iUnixTimeStamp += tmLocal.wSecond;
//-时区时转为秒
iUnixTimeStamp -= (int64)(fZoneHours * 60*60);
return iUnixTimeStamp;
} |