RFC822 的时间日期格式

Code
date-time = [ day "," ] date time ; dd mm yy
; hh:mm:ss zzz
day = "Mon" / "Tue" / "Wed" / "Thu"
/ "Fri" / "Sat" / "Sun"
date = 1*2DIGIT month 2DIGIT ; day month year
; e.g. 20 Jun 82
month = "Jan" / "Feb" / "Mar" / "Apr"
/ "May" / "Jun" / "Jul" / "Aug"
/ "Sep" / "Oct" / "Nov" / "Dec"
time = hour zone ; ANSI and Military
hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
; 00:00:00 - 23:59:59
zone = "UT" / "GMT" ; Universal Time
; North American : UT
/ "EST" / "EDT" ; Eastern: - 5/ - 4
/ "CST" / "CDT" ; Central: - 6/ - 5
/ "MST" / "MDT" ; Mountain: - 7/ - 6
/ "PST" / "PDT" ; Pacific: - 8/ - 7
/ 1ALPHA ; Military: Z = UT;
; A:-1; (J not used)
; M:-12; N:+1; Y:+12
/ ( ("+" / "-") 4DIGIT ) ; Local differential
; hours+min. (HHMM)
date-time = [ day "," ] date time ; dd mm yy
; hh:mm:ss zzz
day = "Mon" / "Tue" / "Wed" / "Thu"
/ "Fri" / "Sat" / "Sun"
date = 1*2DIGIT month 2DIGIT ; day month year
; e.g. 20 Jun 82
month = "Jan" / "Feb" / "Mar" / "Apr"
/ "May" / "Jun" / "Jul" / "Aug"
/ "Sep" / "Oct" / "Nov" / "Dec"
time = hour zone ; ANSI and Military
hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
; 00:00:00 - 23:59:59
zone = "UT" / "GMT" ; Universal Time
; North American : UT
/ "EST" / "EDT" ; Eastern: - 5/ - 4
/ "CST" / "CDT" ; Central: - 6/ - 5
/ "MST" / "MDT" ; Mountain: - 7/ - 6
/ "PST" / "PDT" ; Pacific: - 8/ - 7
/ 1ALPHA ; Military: Z = UT;
; A:-1; (J not used)
; M:-12; N:+1; Y:+12
/ ( ("+" / "-") 4DIGIT ) ; Local differential
; hours+min. (HHMM)
下面是根据上述标准对日期时间的解析
1
virtual HRESULT ParseTime(const NWString& strMIMETime)2

{3
CString str = TEXT("AAAA");4
CString strData(strMIMETime.c_str());5
static const TCHAR * const lpszMonthName[] =6

{TEXT("Jan"),TEXT("Feb"),TEXT("Mar"),TEXT("Apr"),TEXT("May"),7
TEXT("Jun"),TEXT("Jul"),TEXT("Aug"),TEXT("Sep"),TEXT("Oct"),8
TEXT("Nov"),TEXT("Dec")};9

10
strData.Trim(); //删去多余的空格11

12
INT nPosition = 0;13
if(*(LPCTSTR(strData) + 3) == TEXT(',')) //星期信息无用,跳过。14

{15
nPosition = 5;16
}17

18

{//Fix bug: Microsoft NNTP Server return data format invalid,19
//like "Tue,<SPACE><SPACE>26 May 2005
20
21
//We must detect and skip redundant SPACE.22
while(*(LPCTSTR(strData) + nPosition) == TEXT(' '))23
++nPosition;24
}25

26
//天27
CString strTemp = strData.Tokenize(TEXT(" "), nPosition);28
UINT nDay = boost::lexical_cast<UINT>(LPCTSTR(strTemp));29

30
//月31
UINT nMonth = 0; 32
strTemp = strData.Tokenize(TEXT(" "), nPosition);33
for(nMonth = 0; nMonth < 12; ++nMonth)34

{35
if(strTemp == lpszMonthName[nMonth])36
break;37
}38

39
//年份40
strTemp = LPCTSTR(strData.Tokenize(TEXT(" "), nPosition));41
UINT nYear = boost::lexical_cast<UINT>(LPCTSTR(strTemp));42

43
//小时44
strTemp = LPCTSTR(strData.Tokenize(TEXT(":"), nPosition));45
UINT nHour = boost::lexical_cast<UINT>(LPCTSTR(strTemp));46

47
//分钟48
strTemp = LPCTSTR(strData.Tokenize(TEXT(":"), nPosition));49
UINT nMinute = boost::lexical_cast<UINT>(LPCTSTR(strTemp));50
51
//秒数52
UINT nSecond = 0; 53
if(*(LPCTSTR(strData) + nPosition - 1) == TEXT(':'))54

{55
strTemp = LPCTSTR(strData.Tokenize(TEXT(" "), nPosition));56
nSecond = boost::lexical_cast<UINT>(LPCTSTR(strTemp));57
}58

59
//最后处理时区60
time_t nZoneOffset = 0;61
strTemp = strData.Tokenize(TEXT(" "), nPosition);62
//UT,GMT,EST,EDT,CST,CDT,MST,MDT,PST,PDT63
if(3 == strTemp.GetLength())64

{65
if(*(LPCTSTR(strTemp)) == TEXT('E') || *(LPCTSTR(strTemp)) == TEXT('e'))66

{67
if(*(LPCTSTR(strTemp) + 1) == TEXT('S') || *(LPCTSTR(strTemp) + 1) == TEXT('s'))68
nZoneOffset = -5 * 60 * 60;69
else//if(*(LPCTSTR(strTemp) + 1) == TEXT('D') || *(LPCTSTR(strTemp) + 1) == TEXT('d')) 70
nZoneOffset = -4 * 60 * 60;71
}72
else if(*(LPCTSTR(strTemp)) == TEXT('C') || *(LPCTSTR(strTemp)) == TEXT('c'))73

{74
if(*(LPCTSTR(strTemp) + 1) == TEXT('S') || *(LPCTSTR(strTemp) + 1) == TEXT('s'))75
nZoneOffset = -6 * 60 * 60;76
else//if(*(LPCTSTR(strTemp) + 1) == TEXT('D') || *(LPCTSTR(strTemp) + 1) == TEXT('d'))77
nZoneOffset = -5 * 60 * 60;78
}79
else if(*(LPCTSTR(strTemp)) == TEXT('M') || *(LPCTSTR(strTemp)) == TEXT('m'))80

{81
if(*(LPCTSTR(strTemp) + 1) == TEXT('S') || *(LPCTSTR(strTemp) + 1) == TEXT('s'))82
nZoneOffset = -7 * 60 * 60;83
else//if(*(LPCTSTR(strTemp) + 1) == TEXT('D') || *(LPCTSTR(strTemp) + 1) == TEXT('d'))84
nZoneOffset = -6 * 60 * 60;85
}86
else if(*(LPCTSTR(strTemp)) == TEXT('P') || *(LPCTSTR(strTemp)) == TEXT('p'))87

{88
if(*(LPCTSTR(strTemp) + 1) == TEXT('S') || *(LPCTSTR(strTemp) + 1) == TEXT('s'))89
nZoneOffset = -8 * 60 * 60;90
else//if(*(LPCTSTR(strTemp) + 1) == TEXT('D') || *(LPCTSTR(strTemp) + 1) == TEXT('d'))91
nZoneOffset = -7 * 60 * 60;92
}93
else //GMT and UT, the nZoneOffset = 094

{}95
}96
//军方时区97
else if(1 == strTemp.GetLength())98

{99
if(*(LPCTSTR(strTemp)) >= TEXT('A') && *(LPCTSTR(strTemp)) <= TEXT('F'))100
nZoneOffset = -60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('A') + 1);101
else if(*(LPCTSTR(strTemp)) >= TEXT('K') && *(LPCTSTR(strTemp)) <= TEXT('M'))102
nZoneOffset = -60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('A') + 2);103
else if(*(LPCTSTR(strTemp)) >= TEXT('N') && *(LPCTSTR(strTemp)) <= TEXT('Y'))104
nZoneOffset = 60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('N') + 1);105
else if(*(LPCTSTR(strTemp)) >= TEXT('a') && *(LPCTSTR(strTemp)) <= TEXT('f'))106
nZoneOffset = -60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('a') + 1);107
else if(*(LPCTSTR(strTemp)) >= TEXT('k') && *(LPCTSTR(strTemp)) <= TEXT('m'))108
nZoneOffset = -60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('a') + 2);109
else if(*(LPCTSTR(strTemp)) >= TEXT('n') && *(LPCTSTR(strTemp)) <= TEXT('y'))110
nZoneOffset = 60 * 60 * (*(LPCTSTR(strTemp)) - TEXT('n') + 1);111
}112
//数字时区113
else114

{115
int nTimeZone = boost::lexical_cast<int>(LPCTSTR(strTemp));116
nZoneOffset = (60 * (nTimeZone / 100) + nTimeZone % 100) * 60;117
}118

119

struct tm tmRet =
{nSecond, nMinute, nHour, nDay, nMonth, nYear, 0, 0, -1};120

/**//* Fix up the year, using the RFC 2822 rules. Remember that tm_year stores the year - 1900. */121
if (tmRet.tm_year < 50)122
tmRet.tm_year += 100;123
else if(tmRet.tm_year >= 1000)124
tmRet.tm_year -= 1900;125

126
m_tm = _mkgmtime(&tmRet) - nZoneOffset;127
return S_OK;128
}

浙公网安备 33010602011771号