1 /* *****************************************************************
3 * Copyright 2016 Microsoft
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 ******************************************************************/
26 #define TM_BASE_YEAR 1900
28 static const int ydays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
30 bool is_leap_year(int yy)
32 int yyyy = yy + TM_BASE_YEAR;
37 return yyyy % 400 == 0;
43 char * strptime(const char *buf, const char *fmt, struct tm *tm)
49 if ((fmt == NULL) || (tm == NULL))
54 //initialize the tm struct values
55 memset(tm, 0, sizeof(struct tm));
58 while (buf && (c = *fmt++))
72 case 'd': /* day of the month (1..31)*/
73 sscanf(buf, "%2d", &temp);
74 if (temp >= 1 && temp <= 31)
83 case 'H': /* hour (0..23) */
84 sscanf(buf, "%2d", &temp);
85 if (temp >= 0 && temp <= 23)
94 case 'M': /* minute (0..59) */
95 sscanf(buf, "%2d", &temp);
96 if (temp >= 0 && temp <= 59)
105 case 'm': /* month (1..12) */
106 sscanf(buf, "%2d", &temp);
107 if (temp >= 1 && temp <= 12)
109 tm->tm_mon = temp - 1;
116 case 'S': /* seconds (0..59) */
117 sscanf(buf, "%2d", &temp);
118 if (temp >= 0 && temp <= 59)
128 sscanf(buf, "%4d", &temp);
129 if (temp >= 0 && temp <= 9999)
131 tm->tm_year = temp - TM_BASE_YEAR;
149 //calculate tm_wday and tm_yday
150 tm->tm_yday = ydays[tm->tm_mon] + ((is_leap_year(tm->tm_year) && (tm->tm_mon >= 2)) ? 1 : 0) + tm->tm_mday - 1;
152 //1st Jan 1900 was Monday, hence weekday = the number of days from 1/1/1900 modulus 7 + 1
153 tm->tm_wday = (365 * tm->tm_year) + (tm->tm_year / 4) + tm->tm_yday + 1; //1st Jan 1900 was Monday, hence add 1
154 if (is_leap_year(tm->tm_year))