Update Snapshot(2018-02-28)
[platform/upstream/iotivity.git] / resource / csdk / security / src / strptime.c
1 /** @todo: Add Microsoft copyright */
2 #include <stdio.h>
3 #include <ctype.h>
4 #include <time.h>
5 #include <memory.h>
6 #include <stdbool.h>
7
8 #define TM_BASE_YEAR   1900
9
10 static const int ydays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
11
12 bool is_leap_year(int yy)
13 {
14     int yyyy = yy + TM_BASE_YEAR;
15
16     bool bLeap = false;
17     if (yyyy % 100 == 0)
18     {
19         return yyyy % 400 == 0;
20     }
21     return yyyy % 4 == 0;
22 }
23
24
25 char * strptime(const char *buf, const char *fmt, struct tm *tm)
26 {
27     int temp = 0;
28     char c = '\0';
29
30     //check params
31     if ((fmt == NULL) || (tm == NULL))
32     {
33         return NULL;
34     }
35
36     //initialize the tm struct values
37     memset(tm, 0, sizeof(struct tm));
38     tm->tm_mday = 1;
39
40     while (buf && (c = *fmt++))
41     {
42         temp = 0;
43         if (c == '%')
44         {
45             switch (c = *fmt++)
46             {
47             case '%':
48                 if (c != *buf++)
49                 {
50                     return NULL;
51                 }
52                 break;
53
54             case 'd':   /* day of the month (1..31)*/
55                 sscanf(buf, "%2d", &temp);
56                 if (temp >= 1 && temp <= 31)
57                 {
58                     tm->tm_mday = temp;
59                     buf += 2;
60                 }
61                 else
62                     return NULL;
63                 break;
64
65             case 'H':   /* hour (0..23) */
66                 sscanf(buf, "%2d", &temp);
67                 if (temp >= 0 && temp <= 23)
68                 {
69                     tm->tm_hour = temp;
70                     buf += 2;
71                 }
72                 else
73                     return NULL;
74                 break;
75
76             case 'M':   /* minute (0..59) */
77                 sscanf(buf, "%2d", &temp);
78                 if (temp >= 0 && temp <= 59)
79                 {
80                     tm->tm_min = temp;
81                     buf += 2;
82                 }
83                 else
84                     return NULL;
85                 break;
86
87             case 'm':   /* month (1..12) */
88                 sscanf(buf, "%2d", &temp);
89                 if (temp >= 1 && temp <= 12)
90                 {
91                     tm->tm_mon = temp - 1;
92                     buf += 2;
93                 }
94                 else
95                     return NULL;
96                 break;
97
98             case 'S':   /* seconds (0..59) */
99                 sscanf(buf, "%2d", &temp);
100                 if (temp >= 0 && temp <= 59)
101                 {
102                     tm->tm_sec = temp;
103                     buf += 2;
104                 }
105                 else
106                     return NULL;
107                 break;
108
109             case 'Y':   /* year */
110                 sscanf(buf, "%4d", &temp);
111                 if (temp >= 0 && temp <= 9999)
112                 {
113                     tm->tm_year = temp - TM_BASE_YEAR;
114                     buf += 4;
115                 }
116                 else
117                     return NULL;
118                 break;
119
120             default:
121                 return NULL;
122             }
123         }
124         else
125         {
126             if (c != *buf++)
127                 return NULL;
128         }
129     }
130
131     //calculate tm_wday and tm_yday
132     tm->tm_yday = ydays[tm->tm_mon] + ((is_leap_year(tm->tm_year) && (tm->tm_mon >= 2)) ? 1 : 0) + tm->tm_mday - 1;
133
134     //1st Jan 1900 was Monday, hence weekday = the number of days from 1/1/1900  modulus 7 + 1
135     tm->tm_wday = (365 * tm->tm_year) + (tm->tm_year / 4) + tm->tm_yday + 1;        //1st Jan 1900 was Monday, hence add 1
136     if (is_leap_year(tm->tm_year))
137         tm->tm_wday--;
138     tm->tm_wday %= 7;
139
140     return (char*)buf;
141 }