1 /*
2 * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <SupportDefs.h>
8 #include <parsedate.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13
14 #define ABSOLUTE 0
15 #define UNKNOWN 0
16 #define DAY_RELATIVE PARSEDATE_RELATIVE_TIME
17 #define MINUTE_RELATIVE (PARSEDATE_RELATIVE_TIME \
18 | PARSEDATE_MINUTE_RELATIVE_TIME)
19 #define INVALID PARSEDATE_INVALID_DATE
20
21
22 const char*
parsedate_flags_to_string(time_t result,int flags)23 parsedate_flags_to_string(time_t result, int flags)
24 {
25 if (result == -1) {
26 if ((flags & PARSEDATE_INVALID_DATE) != 0)
27 return "invalid";
28 return "unknown";
29 }
30
31 if ((flags & PARSEDATE_RELATIVE_TIME) != 0) {
32 if ((flags & PARSEDATE_MINUTE_RELATIVE_TIME) != 0)
33 return "minute relative";
34
35 return "day relative";
36 }
37
38 return "absolute";
39 }
40
41
42 int
main(int argc,char ** argv)43 main(int argc, char** argv)
44 {
45 time_t now = 1249471430;
46 // August 5th, 2009, 11:23:50 GMT
47
48 struct test {
49 time_t result;
50 const char* date;
51 int flags;
52 bool uses_dst;
53 bool requires_zone_shift;
54 };
55 static const test kDates[] = {
56 {1248739200, "last tuesday", DAY_RELATIVE, true, true},
57 {1249430400, "today", DAY_RELATIVE, true, true},
58 {1249948800, "next tuesday", DAY_RELATIVE, true, true},
59 {1249344000, "tuesday", DAY_RELATIVE, true, true},
60 {1249467830, "last hour", MINUTE_RELATIVE, true, false},
61 {1249475030, "1 hour", MINUTE_RELATIVE, true, false},
62 {now, "now", MINUTE_RELATIVE, true, false},
63 {219456000, "1976-12-15", ABSOLUTE, false, true},
64 {219456000, "12/15/1976", ABSOLUTE, false, true},
65 {219456000, "1976/12/15", ABSOLUTE, false, true},
66 {219456000, "15.12.1976", ABSOLUTE, false, true},
67 {1061596800, "Sat, 08/23/2003", ABSOLUTE, true, true},
68 {1061596800, "Sun, 08/23/2003", ABSOLUTE, true, true},
69 {-1, "", INVALID, false, false},
70 {1249873200, "next monday 3:00", DAY_RELATIVE, true, true},
71 {1249533720, "thursday 4:42", DAY_RELATIVE, true, true},
72 {1249533740, "thursday +4:42:20", DAY_RELATIVE, true, true},
73 {1249533720, "this thursday 4:42", DAY_RELATIVE, true, true},
74 {1249473950, "42 minutes", MINUTE_RELATIVE, true, false},
75 {1250640000, "2 weeks", DAY_RELATIVE, true, true},
76 {1249471730, "next 5 minutes", MINUTE_RELATIVE, true, false},
77 {1249470530, "last 15 minutes", MINUTE_RELATIVE, true, false},
78 {1249470530, "-15 minutes", MINUTE_RELATIVE, true, false},
79 {1249486380, "3:33pm GMT", DAY_RELATIVE, true, false},
80 {739706403, "Mon, June 10th, 1993 10:00:03 am GMT", ABSOLUTE, true, false},
81 {-1, "Sat, 16 Aug Ìîñêîâñêîå âðåìÿ (çèìà)", INVALID, false, false},
82 {739706403, "Mon, June 10th, 1993 10:00:03 am UTC", ABSOLUTE, true, false},
83 {739699203, "Mon, June 10th, 1993 10:00:03 am CEST", ABSOLUTE, true, false},
84 {739706403, "Mon, June 10th, 1993 10:00:03 am +0000", ABSOLUTE, true, false},
85 {-1, "Mon, June 10th, 1993 10:00:03 am 0000", UNKNOWN, true, false},
86 {739702803, "Mon, June 10th, 1993 10:00:03 am +0100", ABSOLUTE, true, false},
87 {739731603, "Mon, June 10th, 1993 10:00:03 am -0700", ABSOLUTE, true, false},
88 {739654203, "Mon, June 10th, 1993 06:00:03 am ACDT", ABSOLUTE, true, false},
89 {1291204800, "01 Dec 10 12:00", ABSOLUTE, false, true},
90 {-1, NULL, 0, false}
91 };
92
93 bool verbose = argc > 1;
94
95 if (verbose)
96 printf("All times relative to: %s (%ld)\n", ctime(&now), now);
97
98 struct TzInfo {
99 const char* timezone;
100 time_t std_offset;
101 time_t dst_offset;
102 };
103 TzInfo tzInfo[] = {
104 { "GMT", 0 },
105 { "Europe/Berlin", -1 * 3600, -2 * 3600 },
106 { "Asia/Tokyo", -9 * 3600, -9 * 3600 },
107 { "America/Los_Angeles", 8 * 3600, 7 * 3600 },
108 { NULL, 0, 0 }
109 };
110
111 for (int tz = 0; tzInfo[tz].timezone != NULL; tz++) {
112 printf("timezone: %s ...\n", tzInfo[tz].timezone);
113 setenv("TZ", tzInfo[tz].timezone, 1);
114 tzset();
115
116 for (int32 i = 0; kDates[i].date; i++) {
117 int flags = 0;
118 time_t result = parsedate_etc(kDates[i].date, now, &flags);
119
120 time_t expectedResult = kDates[i].result;
121 if (kDates[i].requires_zone_shift) {
122 expectedResult +=
123 kDates[i].uses_dst
124 ? tzInfo[tz].dst_offset
125 : tzInfo[tz].std_offset;
126 }
127 bool failure = false;
128 if (flags != kDates[i].flags || result != expectedResult)
129 failure = true;
130 if (failure) {
131 printf(
132 "FAILURE: parsing time at index %ld (should be %ld, %s)\n",
133 i, expectedResult,
134 parsedate_flags_to_string(expectedResult, flags));
135 }
136
137 if (verbose || failure) {
138 printf("\"%s\" = %ld (%s) -> %s", kDates[i].date, result,
139 parsedate_flags_to_string(result, flags), result == -1
140 ? "-\n" : ctime(&result));
141 }
142 }
143 }
144
145 return 0;
146 }
147