diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-01-03 13:45:32 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-01-03 13:45:32 +0100 |
commit | 644f0db9feb71fe62d4084a31575e99cef46acf9 (patch) | |
tree | b63501b13702bdfc81b00a98bc7038d5c7be5c9f | |
parent | 6b8bb25580f25953b3393d37876bcaab144b77b6 (diff) | |
download | gnunet-644f0db9feb71fe62d4084a31575e99cef46acf9.tar.gz gnunet-644f0db9feb71fe62d4084a31575e99cef46acf9.zip |
UTIL: Add RFC3339 timestamps
-rw-r--r-- | src/include/gnunet_strings_lib.h | 29 | ||||
-rw-r--r-- | src/util/strings.c | 39 | ||||
-rw-r--r-- | src/util/test_strings.c | 7 |
3 files changed, 75 insertions, 0 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 2e0c720ee..6c91edd05 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -95,6 +95,20 @@ enum GNUNET_GenericReturnValue | |||
95 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | 95 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, |
96 | struct GNUNET_TIME_Absolute *atime); | 96 | struct GNUNET_TIME_Absolute *atime); |
97 | 97 | ||
98 | /** | ||
99 | * @ingroup time | ||
100 | * Convert a given RFC3339 time to our internal | ||
101 | * representation. | ||
102 | * | ||
103 | * @param rfc3339_time human readable string (e.g. %Y-%m-%dT%H:%M:%SZ) | ||
104 | * @param atime set to the absolute time | ||
105 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
106 | */ | ||
107 | enum GNUNET_GenericReturnValue | ||
108 | GNUNET_STRINGS_rfc3339_time_to_absolute (const char *rfc3339_time, | ||
109 | struct GNUNET_TIME_Absolute *atime); | ||
110 | |||
111 | |||
98 | 112 | ||
99 | /** | 113 | /** |
100 | * @ingroup time | 114 | * @ingroup time |
@@ -270,6 +284,21 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t); | |||
270 | 284 | ||
271 | /** | 285 | /** |
272 | * @ingroup time | 286 | * @ingroup time |
287 | * Like `asctime`, except for GNUnet time. Converts a GNUnet internal | ||
288 | * absolute time (which is in UTC) to a string in local time according to | ||
289 | * RFC3339. | ||
290 | * Note that the returned value will be overwritten if this function | ||
291 | * is called again. | ||
292 | * | ||
293 | * @param t the absolute time to convert | ||
294 | * @return timestamp in human-readable form in local time (RFC3339) | ||
295 | */ | ||
296 | const char * | ||
297 | GNUNET_STRINGS_absolute_time_to_rfc3339 (struct GNUNET_TIME_Absolute t); | ||
298 | |||
299 | |||
300 | /** | ||
301 | * @ingroup time | ||
273 | * Give relative time in human-readable fancy format. | 302 | * Give relative time in human-readable fancy format. |
274 | * This is one of the very few calls in the entire API that is | 303 | * This is one of the very few calls in the entire API that is |
275 | * NOT reentrant! | 304 | * NOT reentrant! |
diff --git a/src/util/strings.c b/src/util/strings.c index db672da87..7be04ea82 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -355,6 +355,45 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | |||
355 | 355 | ||
356 | 356 | ||
357 | enum GNUNET_GenericReturnValue | 357 | enum GNUNET_GenericReturnValue |
358 | GNUNET_STRINGS_rfc3339_time_to_absolute (const char *rfc3339_time, | ||
359 | struct GNUNET_TIME_Absolute *atime) | ||
360 | { | ||
361 | struct tm tv; | ||
362 | time_t t; | ||
363 | const char *eos; | ||
364 | |||
365 | eos = &rfc3339_time[strlen (rfc3339_time)]; | ||
366 | memset (&tv, 0, sizeof(tv)); | ||
367 | /** | ||
368 | * FIXME: There are a lot more formats for RFC3339. | ||
369 | * Actually, we also may want https://www.w3.org/TR/xmlschema11-2/#dateTime | ||
370 | * at some point? | ||
371 | */ | ||
372 | if ((eos != strptime (rfc3339_time, "%Y-%m-%dT%H:%M:%SZ", &tv)) && | ||
373 | (eos != strptime (rfc3339_time, "%Y-%m-%dT%H:%M:%S%z", &tv))) | ||
374 | return GNUNET_SYSERR; | ||
375 | t = timegm (&tv); | ||
376 | atime->abs_value_us = (uint64_t) ((uint64_t) t * 1000LL * 1000LL); | ||
377 | return GNUNET_OK; | ||
378 | } | ||
379 | |||
380 | |||
381 | const char * | ||
382 | GNUNET_STRINGS_absolute_time_to_rfc3339 (struct GNUNET_TIME_Absolute t) | ||
383 | { | ||
384 | static GNUNET_THREAD_LOCAL char buf[255]; | ||
385 | time_t tt; | ||
386 | struct tm *tp; | ||
387 | |||
388 | tt = t.abs_value_us / 1000LL / 1000LL; | ||
389 | tp = gmtime (&tt); | ||
390 | strftime (buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", tp); | ||
391 | |||
392 | return buf; | ||
393 | } | ||
394 | |||
395 | |||
396 | enum GNUNET_GenericReturnValue | ||
358 | GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, | 397 | GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, |
359 | struct GNUNET_TIME_Timestamp *atime) | 398 | struct GNUNET_TIME_Timestamp *atime) |
360 | { | 399 | { |
diff --git a/src/util/test_strings.c b/src/util/test_strings.c index d986486d0..0167e5329 100644 --- a/src/util/test_strings.c +++ b/src/util/test_strings.c | |||
@@ -131,6 +131,13 @@ main (int argc, char *argv[]) | |||
131 | GNUNET_assert (0); | 131 | GNUNET_assert (0); |
132 | } | 132 | } |
133 | 133 | ||
134 | at.abs_value_us = 1577906604000000; /* 2020-01-01T19:23:24Z */ | ||
135 | bc = GNUNET_STRINGS_absolute_time_to_rfc3339 (at); | ||
136 | GNUNET_assert (0 == strcmp ("2020-01-01T19:23:24Z", bc)); | ||
137 | GNUNET_assert (GNUNET_OK == | ||
138 | GNUNET_STRINGS_rfc3339_time_to_absolute (bc, &atx)); | ||
139 | GNUNET_assert (at.abs_value_us == atx.abs_value_us); | ||
140 | |||
134 | GNUNET_log_skip (2, GNUNET_NO); | 141 | GNUNET_log_skip (2, GNUNET_NO); |
135 | b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown"); | 142 | b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "unknown"); |
136 | GNUNET_log_skip (0, GNUNET_YES); | 143 | GNUNET_log_skip (0, GNUNET_YES); |