62 while ((opt = getopt(argc, argv,
"V:")) != -1) {
86 {0,
"Thu, 01 Jan 1970 00:00:00 GMT",
"Thu, 01 Jan 1970 00:00:00 +0000",
"1970-01-01T00:00:00+00:00", 3600,
87 "Thu, 01 Jan 1970 01:00:00 +0100",
"1970-01-01T01:00:00+01:00"},
88 {784111777,
"Sun, 06 Nov 1994 08:49:37 GMT",
"Sun, 06 Nov 1994 08:49:37 +0000",
"1994-11-06T08:49:37+00:00", 3600,
89 "Sun, 06 Nov 1994 09:49:37 +0100",
"1994-11-06T09:49:37+01:00"},
90 {951782400,
"Tue, 29 Feb 2000 00:00:00 GMT",
"Tue, 29 Feb 2000 00:00:00 +0000",
"2000-02-29T00:00:00+00:00", 3600,
91 "Tue, 29 Feb 2000 01:00:00 +0100",
"2000-02-29T01:00:00+01:00"},
92 {1792794600,
"Fri, 23 Oct 2026 22:30:00 GMT",
"Fri, 23 Oct 2026 22:30:00 +0000",
"2026-10-23T22:30:00+00:00", 7200,
93 "Sat, 24 Oct 2026 00:30:00 +0200",
"2026-10-24T00:30:00+02:00"},
94 {-1,
"Wed, 31 Dec 1969 23:59:59 GMT",
"Wed, 31 Dec 1969 23:59:59 +0000",
"1969-12-31T23:59:59+00:00", 3600,
95 "Thu, 01 Jan 1970 00:59:59 +0100",
"1970-01-01T00:59:59+01:00"},
99 for (i = 0; i <
sizeof(v) /
sizeof(v[0]); i++) {
100 time_t t = (time_t)v[i].t;
107 expect_true(
"negative offset",
n_time_rfc3339(0, -(5 * 3600 + 30 * 60), buf,
sizeof(buf)) && strcmp(buf,
"1969-12-31T18:30:00-05:30") == 0);
108 expect_true(
"negative offset RFC 2822",
n_time_rfc2822(0, -(5 * 3600 + 30 * 60), buf,
sizeof(buf)) && strcmp(buf,
"Wed, 31 Dec 1969 18:30:00 -0530") == 0);
109 if (
sizeof(time_t) >= 8) {
110 expect_true(
"year 9999",
n_time_http_date((time_t)253402300799LL, buf,
sizeof(buf)) && strcmp(buf,
"Fri, 31 Dec 9999 23:59:59 GMT") == 0);
111 expect_true(
"year 1",
n_time_http_date((time_t)-62135596800LL, buf,
sizeof(buf)) && strcmp(buf,
"Mon, 01 Jan 0001 00:00:00 GMT") == 0);
131static int parses(
int http,
const char* s,
int ok,
long long want) {
132 time_t t = (time_t)12345;
135 return r == FALSE && t == (time_t)12345;
136 return r == TRUE && (
long long)t == want;
144 expect_true(
"HTTP date parses",
parses(1,
"Sun, 06 Nov 1994 08:49:37 GMT", 1, 784111777));
145 expect_true(
"HTTP date, 29 Feb 2000",
parses(1,
"Tue, 29 Feb 2000 00:00:00 GMT", 1, 951782400));
146 expect_true(
"HTTP date before 1970",
parses(1,
"Wed, 31 Dec 1969 23:59:59 GMT", 1, -1));
147 expect_true(
"wrong weekday refused",
parses(1,
"Mon, 06 Nov 1994 08:49:37 GMT", 0, 0));
148 expect_true(
"29 Feb 2100 refused",
parses(1,
"Mon, 29 Feb 2100 00:00:00 GMT", 0, 0));
149 expect_true(
"hour 24 refused",
parses(1,
"Sun, 06 Nov 1994 24:00:00 GMT", 0, 0));
150 expect_true(
"leap second refused",
parses(1,
"Sun, 06 Nov 1994 23:59:60 GMT", 0, 0));
151 expect_true(
"lowercase month refused",
parses(1,
"Sun, 06 nov 1994 08:49:37 GMT", 0, 0));
152 expect_true(
"other zone refused",
parses(1,
"Sun, 06 Nov 1994 08:49:37 UTC", 0, 0));
153 expect_true(
"RFC 850 form refused",
parses(1,
"Sunday, 06-Nov-94 08:49:37 GMT", 0, 0));
155 expect_true(
"trailing byte refused",
parses(1,
"Sun, 06 Nov 1994 08:49:37 GMTX", 0, 0));
156 expect_true(
"sign in a number refused",
parses(1,
"Sun, +6 Nov 1994 08:49:37 GMT", 0, 0));
160 expect_true(
"RFC 3339 offset",
parses(0,
"2026-10-24T00:30:00+02:00", 1, 1792794600));
161 expect_true(
"RFC 3339 negative offset",
parses(0,
"1969-12-31T18:30:00-05:30", 1, 0));
170 for (t = -2000000000LL; t < 4000000000LL; t += 7777777) {
172 if (
sizeof(time_t) < 8 && (t > 2147483647LL || t < -2147483647LL))
175 n_log(
LOG_ERR,
"FAIL: HTTP date round trip at %lld (%s)", t, buf);
180 n_log(
LOG_ERR,
"FAIL: RFC 3339 round trip at %lld (%s)", t, buf);
191int main(
int argc,
char** argv) {
193 fprintf(stderr,
"usage: %s [-V LOG_LEVEL]\n", argv[0]);
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
static void test_parse(void)
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_NOTICE
normal but significant condition
#define LOG_INFO
informational
int n_time_parse_http_date(const char *s, size_t len, time_t *t)
parse an IMF-fixdate HTTP date strictly
int n_time_rfc2822(time_t t, long offset, char *out, size_t size)
format t as an RFC 2822 date at offset seconds east of UTC
int n_time_parse_rfc3339(const char *s, size_t len, time_t *t)
parse "YYYY-MM-DD[T| ]HH:MM:SS[Z|+hh:mm|-hh:mm]" (UTC without a zone)
#define N_TIME_RFC2822_LEN
buffer size for n_time_rfc2822(): "Thu, 01 Jan 1970 00:00:00 +0000" + NUL
#define N_TIME_HTTP_DATE_LEN
buffer size for n_time_http_date(): "Thu, 01 Jan 1970 00:00:00 GMT" + NUL
int n_time_http_date(time_t t, char *out, size_t size)
format t as an HTTP date (RFC 9110 IMF-fixdate, always GMT)
int n_time_rfc3339(time_t t, long offset, char *out, size_t size)
format t as RFC 3339 at offset seconds east of UTC ("+00:00" for UTC)
#define N_TIME_RFC3339_LEN
buffer size for n_time_rfc3339(): "1970-01-01T00:00:00+00:00" + NUL
Common headers and low-level functions & define.