annotate src/lib/iso8601-date.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21389
diff changeset
1 /* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
15188
d66421812d2a Added/updated some copyright comments.
Timo Sirainen <tss@iki.fi>
parents: 14629
diff changeset
2
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
3 #include "lib.h"
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
4 #include "utc-offset.h"
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
5 #include "utc-mktime.h"
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
6 #include "iso8601-date.h"
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
7
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
8 #include <ctype.h>
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
9
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
10 /* RFC3339/ISO8601 date-time syntax
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
11
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
12 date-fullyear = 4DIGIT
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
13 date-month = 2DIGIT ; 01-12
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
14 date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
15 ; month/year
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
16 time-hour = 2DIGIT ; 00-23
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
17 time-minute = 2DIGIT ; 00-59
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
18 time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
19 ; rules
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
20 time-secfrac = "." 1*DIGIT
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
21 time-numoffset = ("+" / "-") time-hour ":" time-minute
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
22 time-offset = "Z" / time-numoffset
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
23
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
24 partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
25 full-date = date-fullyear "-" date-month "-" date-mday
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
26 full-time = partial-time time-offset
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
27
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
28 date-time = full-date "T" full-time
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
29 */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
30
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
31 struct iso8601_date_parser {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
32 const unsigned char *cur, *end;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
33
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
34 struct tm tm;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
35 int timezone_offset;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
36 };
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
37
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
38 static inline int
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
39 iso8601_date_parse_number(struct iso8601_date_parser *parser,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
40 int digits, int *number_r)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
41 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
42 int i;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
43
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
44 if (parser->cur >= parser->end || !i_isdigit(parser->cur[0]))
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
45 return 0;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
46
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
47 *number_r = parser->cur[0] - '0';
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
48 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
49
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
50 for (i=0; i < digits-1; i++) {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
51 if (parser->cur >= parser->end || !i_isdigit(parser->cur[0]))
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
52 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
53 *number_r = ((*number_r) * 10) + parser->cur[0] - '0';
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
54 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
55 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
56 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
57 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
58
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
59 static int
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
60 iso8601_date_parse_secfrac(struct iso8601_date_parser *parser)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
61 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
62 /* time-secfrac = "." 1*DIGIT
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
63
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
64 NOTE: Currently not applied anywhere, so fraction is just skipped.
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
65 */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
66
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
67 /* "." */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
68 if (parser->cur >= parser->end || parser->cur[0] != '.')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
69 return 0;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
70 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
71
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
72 /* 1DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
73 if (parser->cur >= parser->end || !i_isdigit(parser->cur[0]))
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
74 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
75 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
76
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
77 /* *DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
78 while (parser->cur < parser->end && i_isdigit(parser->cur[0]))
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
79 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
80 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
81 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
82
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
83 static int is08601_date_parse_time_offset(struct iso8601_date_parser *parser)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
84 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
85 int tz_sign = 1, tz_hour = 0, tz_min = 0;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
86
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
87 /* time-offset = "Z" / time-numoffset
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
88 time-numoffset = ("+" / "-") time-hour ":" time-minute
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
89 time-hour = 2DIGIT ; 00-23
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
90 time-minute = 2DIGIT ; 00-59
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
91 */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
92
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
93 if (parser->cur >= parser->end)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
94 return 0;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
95
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
96 /* time-offset = "Z" / time-numoffset */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
97 switch (parser->cur[0]) {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
98 case '-':
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
99 tz_sign = -1;
17474
1aca4e8811dc Added "fall through" comments to switch statements where break is intentionally missing.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
100 /* fall through */
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
101 case '+':
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
102 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
103
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
104 /* time-hour = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
105 if (iso8601_date_parse_number(parser, 2, &tz_hour) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
106 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
107 if (tz_hour > 23)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
108 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
109
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
110 /* ":" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
111 if (parser->cur >= parser->end || parser->cur[0] != ':')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
112 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
113 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
114
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
115 /* time-minute = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
116 if (iso8601_date_parse_number(parser, 2, &tz_min) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
117 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
118 if (tz_min > 59)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
119 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
120 break;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
121 case 'Z':
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
122 case 'z':
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
123 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
124 break;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
125 default:
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
126 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
127 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
128
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
129 parser->timezone_offset = tz_sign*(tz_hour*60 + tz_min);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
130 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
131 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
132
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
133 static int is08601_date_parse_full_time(struct iso8601_date_parser *parser)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
134 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
135 /* full-time = partial-time time-offset
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
136 partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
137 time-hour = 2DIGIT ; 00-23
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
138 time-minute = 2DIGIT ; 00-59
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
139 time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
140 ; rules
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
141 */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
142
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
143 /* time-hour = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
144 if (iso8601_date_parse_number(parser, 2, &parser->tm.tm_hour) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
145 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
146
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
147 /* ":" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
148 if (parser->cur >= parser->end || parser->cur[0] != ':')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
149 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
150 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
151
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
152 /* time-minute = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
153 if (iso8601_date_parse_number(parser, 2, &parser->tm.tm_min) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
154 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
155
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
156 /* ":" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
157 if (parser->cur >= parser->end || parser->cur[0] != ':')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
158 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
159 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
160
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
161 /* time-second = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
162 if (iso8601_date_parse_number(parser, 2, &parser->tm.tm_sec) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
163 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
164
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
165 /* [time-secfrac] */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
166 if (iso8601_date_parse_secfrac(parser) < 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
167 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
168
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
169 /* time-offset */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
170 if (is08601_date_parse_time_offset(parser) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
171 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
172 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
173 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
174
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
175 static int is08601_date_parse_full_date(struct iso8601_date_parser *parser)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
176 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
177 /* full-date = date-fullyear "-" date-month "-" date-mday
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
178 date-fullyear = 4DIGIT
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
179 date-month = 2DIGIT ; 01-12
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
180 date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
181 ; month/year
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
182 */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
183
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
184 /* date-fullyear = 4DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
185 if (iso8601_date_parse_number(parser, 4, &parser->tm.tm_year) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
186 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
187 if (parser->tm.tm_year < 1900)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
188 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
189 parser->tm.tm_year -= 1900;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
190
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
191 /* "-" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
192 if (parser->cur >= parser->end || parser->cur[0] != '-')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
193 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
194 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
195
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
196 /* date-month = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
197 if (iso8601_date_parse_number(parser, 2, &parser->tm.tm_mon) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
198 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
199 parser->tm.tm_mon -= 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
200
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
201 /* "-" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
202 if (parser->cur >= parser->end || parser->cur[0] != '-')
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
203 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
204 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
205
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
206 /* time-second = 2DIGIT */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
207 if (iso8601_date_parse_number(parser, 2, &parser->tm.tm_mday) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
208 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
209 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
210 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
211
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
212 static int iso8601_date_parse_date_time(struct iso8601_date_parser *parser)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
213 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
214 /* date-time = full-date "T" full-time */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
215
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
216 /* full-date */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
217 if (is08601_date_parse_full_date(parser) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
218 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
219
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
220 /* "T" */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
221 if (parser->cur >= parser->end ||
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
222 (parser->cur[0] != 'T' && parser->cur[0] != 't'))
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
223 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
224 parser->cur++;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
225
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
226 /* full-time */
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
227 if (is08601_date_parse_full_time(parser) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
228 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
229
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
230 if (parser->cur != parser->end)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
231 return -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
232 return 1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
233 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
234
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
235 static bool
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
236 iso8601_date_do_parse(const unsigned char *data, size_t size, struct tm *tm_r,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
237 time_t *timestamp_r, int *timezone_offset_r)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
238 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
239 struct iso8601_date_parser parser;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
240 time_t timestamp;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
241
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
242 i_zero(&parser);
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
243 parser.cur = data;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
244 parser.end = data + size;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
245
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
246 if (iso8601_date_parse_date_time(&parser) <= 0)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
247 return FALSE;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
248
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
249 parser.tm.tm_isdst = -1;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
250 timestamp = utc_mktime(&parser.tm);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
251 if (timestamp == (time_t)-1)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
252 return FALSE;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
253
14629
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
254 *timezone_offset_r = parser.timezone_offset;
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
255 *tm_r = parser.tm;
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
256 *timestamp_r = timestamp - parser.timezone_offset * 60;
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
257 return TRUE;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
258 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
259
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
260 bool iso8601_date_parse(const unsigned char *data, size_t size,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
261 time_t *timestamp_r, int *timezone_offset_r)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
262 {
14629
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
263 struct tm tm;
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
264
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
265 return iso8601_date_do_parse(data, size, &tm,
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
266 timestamp_r, timezone_offset_r);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
267 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
268
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
269 bool iso8601_date_parse_tm(const unsigned char *data, size_t size,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
270 struct tm *tm_r, int *timezone_offset_r)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
271 {
14629
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
272 time_t timestamp;
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
273
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
274 return iso8601_date_do_parse(data, size, tm_r,
c93ca5e46a8a Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents: 14586
diff changeset
275 &timestamp, timezone_offset_r);
14586
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
276 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
277
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
278 const char *iso8601_date_create_tm(struct tm *tm, int timezone_offset)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
279 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
280 const char *time_offset;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
281
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
282 if (timezone_offset == INT_MAX)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
283 time_offset = "Z";
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
284 else {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
285 char sign = '+';
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
286 if (timezone_offset < 0) {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
287 timezone_offset = -timezone_offset;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
288 sign = '-';
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
289 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
290 time_offset = t_strdup_printf("%c%02d:%02d", sign,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
291 timezone_offset / 60,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
292 timezone_offset % 60);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
293 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
294
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
295 return t_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02d%s",
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
296 tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday,
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
297 tm->tm_hour, tm->tm_min, tm->tm_sec, time_offset);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
298 }
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
299
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
300 const char *iso8601_date_create(time_t timestamp)
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
301 {
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
302 struct tm *tm;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
303 int timezone_offset;
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
304
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
305 tm = localtime(&timestamp);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
306 timezone_offset = utc_offset(tm, timestamp);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
307
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
308 return iso8601_date_create_tm(tm, timezone_offset);
21d67121985a Adds ISO8601/RFC3339 date format parsing and construction support.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
309 }