/Users/alexjokela/projects/lattice/src/datetime_ops.c
Line | Count | Source |
1 | | #define _XOPEN_SOURCE 700 /* for strptime */ |
2 | | #include "datetime_ops.h" |
3 | | #include <time.h> |
4 | | #include <stdlib.h> |
5 | | #include <string.h> |
6 | | #include <stdio.h> |
7 | | |
8 | 12 | char *datetime_format(int64_t epoch_ms, const char *fmt, char **err) { |
9 | 12 | time_t secs = (time_t)(epoch_ms / 1000); |
10 | 12 | struct tm tm; |
11 | 12 | if (localtime_r(&secs, &tm) == NULL) { |
12 | 0 | *err = strdup("time_format: failed to convert timestamp"); |
13 | 0 | return NULL; |
14 | 0 | } |
15 | | |
16 | 12 | char buf[512]; |
17 | 12 | size_t n = strftime(buf, sizeof(buf), fmt, &tm); |
18 | 12 | if (n == 0) { |
19 | 0 | *err = strdup("time_format: format produced empty string or exceeded buffer"); |
20 | 0 | return NULL; |
21 | 0 | } |
22 | | |
23 | 12 | return strdup(buf); |
24 | 12 | } |
25 | | |
26 | 12 | int64_t datetime_parse(const char *str, const char *fmt, char **err) { |
27 | 12 | struct tm tm; |
28 | 12 | memset(&tm, 0, sizeof(tm)); |
29 | 12 | tm.tm_isdst = -1; /* let mktime determine DST */ |
30 | | |
31 | 12 | char *rest = strptime(str, fmt, &tm); |
32 | 12 | if (rest == NULL) { |
33 | 3 | char msg[256]; |
34 | 3 | snprintf(msg, sizeof(msg), |
35 | 3 | "time_parse: failed to parse \"%s\" with format \"%s\"", |
36 | 3 | str, fmt); |
37 | 3 | *err = strdup(msg); |
38 | 3 | return 0; |
39 | 3 | } |
40 | | |
41 | 9 | time_t secs = mktime(&tm); |
42 | 9 | if (secs == (time_t)-1) { |
43 | 0 | *err = strdup("time_parse: mktime failed to convert parsed time"); |
44 | 0 | return 0; |
45 | 0 | } |
46 | | |
47 | 9 | return (int64_t)secs * 1000; |
48 | 9 | } |