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