1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
| | // SPDX-License-Identifier: MIT
#define _GNU_SOURCE /* For tm_gmtoff */
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "test.h"
static void checkStrptime(const char *s, const char *format, const struct tm *expected) {
size_t n = offsetof(struct tm, tm_isdst);
struct tm tm = { };
const char *ret;
ret = strptime(s, format, &tm);
if (!ret || *ret != '\0') {
t_error("\"%s\": failed to parse \"%s\"\n", format, s);
} else if (memcmp(&tm, expected, n)) {
char buf1[64];
char buf2[64];
strftime(buf1, sizeof(buf1), "%FT%H:%M:%S%Z (day %j: %a)", expected);
strftime(buf2, sizeof(buf2), "%FT%H:%M:%S%Z (day %j: %a)", &tm);
t_error("\"%s\": for \"%s\" expected %s but got %s\n", format, s, buf1, buf2);
}
}
static void checkStrptimeTz(const char *s, int h, int m) {
long int expected = h * 3600 + m * 60;
struct tm tm = { };
const char *ret;
ret = strptime(s, "%z", &tm);
if (!ret || *ret != '\0') {
t_error("\"%%z\": failed to parse \"%s\"\n", s);
} else if (tm.tm_gmtoff != expected) {
t_error("\"%%z\": for \"%s\" expected tm_gmtoff %ld but got %ld\n", s, tm.tm_gmtoff, expected);
}
}
static struct tm tm1 = {
.tm_sec = 8,
.tm_min = 57,
.tm_hour = 20,
.tm_mday = 0,
.tm_mon = 0,
.tm_year = 0,
.tm_wday = 0,
.tm_yday = 0,
.tm_isdst = 0,
};
static struct tm tm2 = {
.tm_sec = 0,
.tm_min = 0,
.tm_hour = 0,
.tm_mday = 25,
.tm_mon = 8 - 1,
.tm_year = 1991 - 1900,
.tm_wday = 0,
.tm_yday = 237 - 1,
.tm_isdst = 0,
};
static struct tm tm3 = {
.tm_sec = 0,
.tm_min = 0,
.tm_hour = 0,
.tm_mday = 21,
.tm_mon = 10 - 1,
.tm_year = 2015 - 1900,
.tm_wday = 3,
.tm_yday = 294 - 1,
.tm_isdst = 0,
};
static struct tm tm4 = {
.tm_sec = 0,
.tm_min = 0,
.tm_hour = 0,
.tm_mday = 10,
.tm_mon = 7 - 1,
.tm_year = 1856 - 1900,
.tm_wday = 4,
.tm_yday = 192 - 1,
.tm_isdst = 0,
};
int main() {
setenv("TZ", "UTC0", 1);
/* Time */
checkStrptime("20:57:08", "%H:%M:%S", &tm1);
checkStrptime("20:57:8", "%R:%S", &tm1);
checkStrptime("20:57:08", "%T", &tm1);
/* Format */
checkStrptime("20:57:08", "%H : %M : %S", &tm1);
checkStrptime("20 57 08", "%H %M %S", &tm1);
checkStrptime("20%57%08", "%H %% %M%%%S", &tm1);
checkStrptime("foo20bar57qux08 ", "foo %Hbar %M qux%S ", &tm1);
/* Date */
checkStrptime("1991-08-25", "%Y-%m-%d", &tm2);
checkStrptime("25.08.91", "%d.%m.%y", &tm2);
checkStrptime("08/25/91", "%D", &tm2);
checkStrptime("21.10.15", "%d.%m.%y", &tm3);
checkStrptime("10.7.56 in 18th", "%d.%m.%y in %C th", &tm4);
/* Glibc */
checkStrptime("1856-07-10", "%F", &tm4);
checkStrptime("683078400", "%s", &tm2);
checkStrptimeTz("+0200", 2, 0);
checkStrptimeTz("-0530", -5, -30);
checkStrptimeTz("-06", -6, 0);
return t_status;
}
|