base/time/m_time_parse.c
/* RFC-822/ISO 8601 standard timezone specification parser.
 *
 * RFC-822
 * 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)
 *
 *     Time zone may be indicated in several ways.  "UT" is Univer-
 * sal  Time  (formerly called "Greenwich Mean Time"); "GMT" is per-
 * mitted as a reference to Universal Time.  The  military  standard
 * uses  a  single  character for each zone.  "Z" is Universal Time.
 * "A" indicates one hour earlier, and "M" indicates 12  hours  ear-
 * lier;  "N"  is  one  hour  later, and "Y" is 12 hours later.  The
 * letter "J" is not used.  The other remaining two forms are  taken
 * from ANSI standard X3.51-1975.  One allows explicit indication of
 * the amount of offset from UT; the other uses  common  3-character
 * strings for indicating time zones in North America.
 *
 * ISO 8601
 * [+-]hh:mm
 * [+-]hhmm
 * [+-]hh
 */
RFC-822/ISO 8601 standard timezone specification parser.

Time zone may be indicated in several ways.


RFC - 822 / ISO 8601 standard timezone specification parser . Time zone may be indicated in several ways .
static M_bool M_time_getoffset(const char **s, M_time_t *gmtoff)
{
	M_time_t x;
	M_bool   isneg = M_FALSE;
	if (s == NULL || *s == NULL || **s == '\0' || gmtoff == NULL)
		return M_FALSE;
	*gmtoff = 0;
	switch (**s) {
		case 'U':
		case 'G':
			if (M_str_eq_max(*s, "UTC", 3) || M_str_eq_max(*s, "GMT", 3)) {
				*s += 3;
			} else if (M_str_eq_max(*s, "UT", 2)) {
				*s += 2;
			} else if (**s == 'U') {
				(*s)++;
				*gmtoff = 8;
			} else if (**s == 'G') {
				(*s)++;
				*gmtoff = -7;
			} else {
				return M_FALSE;
			}
			break;
		case 'E':
			if (M_str_eq_max(*s, "EST", 3)) {
				*s += 3;
				*gmtoff = -5;
			} else if (M_str_eq_max(*s, "EDT", 3)) {
				*s += 3;
				*gmtoff = -4;
			} else if (**s == 'E') {
				(*s)++;
				*gmtoff = -5;
			} else {
				return M_FALSE;
			}
			break;
		case 'C':
			if (M_str_eq_max(*s, "CST", 3)) {
				*s += 3;
				*gmtoff = -6;
			} else if (M_str_caseeq_max(*s, "cdt", 3)) {
				*s += 3;
				*gmtoff = -5;
			} else if (**s == 'C') {
				(*s)++;
				*gmtoff = -3;
			} else {
				return M_FALSE;
			}
			break;
		case 'M':
			if (M_str_eq_max(*s, "MST", 3)) {
				*s += 3;
				*gmtoff = -7;
			} else if (M_str_eq_max(*s, "MDT", 3)) {
				*s += 3;
				*gmtoff = -6;
			} else if (**s == 'M') {
				(*s)++;
				*gmtoff = -12;
			} else {
				return M_FALSE;
			}
			break;
		case 'P':
			if (M_str_eq_max(*s, "PST", 3)) {
				*s += 3;
				*gmtoff = -8;
			} else if (M_str_eq_max(*s, "PDT", 3)) {
				*s += 3;
				*gmtoff = -7;
			} else if (**s == 'M') {
				(*s)++;
				*gmtoff = 3;
			} else {
				return M_FALSE;
			}
			break;
		case 'A':
		case 'B':
		case 'D':
		case 'F':
		case 'H':
		case 'I':
			*gmtoff = (**s - 'A' + 1) * -1;
			(*s)++;
			break;
		case 'K':
		case 'L':
			*gmtoff = (**s - 'A') * -1;
			(*s)++;
			break;
		case 'N':
		case 'O':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
			*gmtoff = (**s - 'N' + 1);
			(*s)++;
			break;
		case 'Z':
			(*s)++;
			break;
		case '-':
			isneg = M_TRUE;
		case '+':
			(*s)++;
		case '0':
		case '1':
		case '2':
			x = (M_time_t)M_time_getnum(s, 2);
			*gmtoff = x*60*60;
			if (**s == ':') {
				(*s)++;
			}
			if (M_chr_isdigit(**s)) {
				x = (M_time_t)M_time_getnum(s, 2);
				*gmtoff += x*60;
			}
			if (isneg)
				*gmtoff *= -1;
			break;
		default:
			return M_FALSE;
	}
	return M_TRUE;
}
static M_bool M_time_getoffset ( const char * * s , M_time_t * gmtoff ) { M_time_t x ; M_bool isneg = M_FALSE ; if ( s == NULL || * s == NULL || * * s == ' \0 ' || gmtoff == NULL ) return M_FALSE ; * gmtoff = 0 ; switch ( * * s ) { case ' ' : case ' ' : if ( M_str_eq_max ( * s , " " , 3 ) || M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; } else if ( M_str_eq_max ( * s , " " , 2 ) ) { * s += 2 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = 8 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = -7 ; } else { return M_FALSE ; } break ; case ' ' : if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -5 ; } else if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -4 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = -5 ; } else { return M_FALSE ; } break ; case ' ' : if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -6 ; } else if ( M_str_caseeq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -5 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = -3 ; } else { return M_FALSE ; } break ; case ' ' : if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -7 ; } else if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -6 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = -12 ; } else { return M_FALSE ; } break ; case ' ' : if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -8 ; } else if ( M_str_eq_max ( * s , " " , 3 ) ) { * s += 3 ; * gmtoff = -7 ; } else if ( * * s == ' ' ) { ( * s ) ++ ; * gmtoff = 3 ; } else { return M_FALSE ; } break ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : * gmtoff = ( * * s - ' ' + 1 ) * -1 ; ( * s ) ++ ; break ; case ' ' : case ' ' : * gmtoff = ( * * s - ' ' ) * -1 ; ( * s ) ++ ; break ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : * gmtoff = ( * * s - ' ' + 1 ) ; ( * s ) ++ ; break ; case ' ' : ( * s ) ++ ; break ; case ' ' : isneg = M_TRUE ; case ' ' : ( * s ) ++ ; case ' ' : case ' ' : case ' ' : x = ( M_time_t ) M_time_getnum ( s , 2 ) ; * gmtoff = x * 60 * 60 ; if ( * * s == ' ' ) { ( * s ) ++ ; } if ( M_chr_isdigit ( * * s ) ) { x = ( M_time_t ) M_time_getnum ( s , 2 ) ; * gmtoff += x * 60 ; } if ( isneg ) * gmtoff *= -1 ; break ; default : return M_FALSE ; } return M_TRUE ; }
RFC-822/ISO 8601 standard timezone specification parser.
RFC - 822 / ISO 8601 standard timezone specification parser .
/* UTC identifiers */ /* UTC. No offset nothing to do. */ /* Fallthrough */ /* Fallthrough */ /* Get hours. */ /* Check for : and skip past. */ /* Check if we have minutes. */ /* Get minutes. */ /* Set direction. */