2.64 xs_time.h
  1/* copyright (c) 2022 - 2024 grunfink et al. / MIT license */
  2
  3#ifndef _XS_TIME_H
  4
  5#define _XS_TIME_H
  6
  7#include <time.h>
  8
  9xs_str *xs_str_time(time_t t, const char *fmt, int local);
 10#define xs_str_localtime(t, fmt) xs_str_time(t, fmt, 1)
 11#define xs_str_utctime(t, fmt)   xs_str_time(t, fmt, 0)
 12#define xs_str_iso_date(t) xs_str_time(t, "%Y-%m-%dT%H:%M:%SZ", 0)
 13time_t xs_parse_iso_date(const char *iso_date, int local);
 14time_t xs_parse_time(const char *str, const char *fmt, int local);
 15#define xs_parse_localtime(str, fmt) xs_parse_time(str, fmt, 1)
 16#define xs_parse_utctime(str, fmt) xs_parse_time(str, fmt, 0)
 17xs_str *xs_str_time_diff(time_t time_diff);
 18
 19#ifdef XS_IMPLEMENTATION
 20
 21xs_str *xs_str_time(time_t t, const char *fmt, int local)
 22/* returns a string with a formated time */
 23{
 24    struct tm tm;
 25    char tmp[64];
 26
 27    if (t == 0)
 28        t = time(NULL);
 29
 30    if (local)
 31        localtime_r(&t, &tm);
 32    else
 33        gmtime_r(&t, &tm);
 34
 35    strftime(tmp, sizeof(tmp), fmt, &tm);
 36
 37    return xs_str_new(tmp);
 38}
 39
 40
 41xs_str *xs_str_time_diff(time_t time_diff)
 42/* returns time_diff in seconds to 'human' units (d:hh:mm:ss) */
 43{
 44    int secs  = time_diff % 60;
 45    int mins  = (time_diff /= 60) % 60;
 46    int hours = (time_diff /= 60) % 24;
 47    int days  = (time_diff /= 24);
 48
 49    return xs_fmt("%d:%02d:%02d:%02d", days, hours, mins, secs);
 50}
 51
 52
 53char *strptime(const char *s, const char *format, struct tm *tm);
 54
 55time_t xs_parse_time(const char *str, const char *fmt, int local)
 56{
 57    time_t t = 0;
 58
 59#ifndef WITHOUT_STRPTIME
 60
 61    struct tm tm = {0};
 62
 63    strptime(str, fmt, &tm);
 64
 65    /* try to guess the Daylight Saving Time */
 66    if (local)
 67        tm.tm_isdst = -1;
 68
 69    t = local ? mktime(&tm) : timegm(&tm);
 70
 71#endif /* WITHOUT_STRPTIME */
 72
 73    return t;
 74}
 75
 76
 77time_t xs_parse_iso_date(const char *iso_date, int local)
 78/* parses a YYYY-MM-DDTHH:MM:SS date string */
 79{
 80    time_t t = 0;
 81
 82#ifndef WITHOUT_STRPTIME
 83
 84    t = xs_parse_time(iso_date, "%Y-%m-%dT%H:%M:%S", local);
 85
 86#else /* WITHOUT_STRPTIME */
 87
 88    struct tm tm = {0};
 89
 90    if (sscanf(iso_date, "%d-%d-%dT%d:%d:%d",
 91        &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
 92        &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {
 93
 94        tm.tm_year -= 1900;
 95        tm.tm_mon -= 1;
 96
 97        if (local)
 98            tm.tm_isdst = -1;
 99
100        t = local ? mktime(&tm) : timegm(&tm);
101    }
102
103#endif /* WITHOUT_STRPTIME */
104
105    return t;
106}
107
108
109#endif /* XS_IMPLEMENTATION */
110
111#endif /* _XS_TIME_H */