time-util.c revision bcb4e51a409d94ae670de96afb8483a4f7855294
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "lib.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "time-util.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <time.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#define STRFTIME_MAX_BUFSIZE (1024*64)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaint timeval_cmp(const struct timeval *tv1, const struct timeval *tv2)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_sec < tv2->tv_sec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return -1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_sec > tv2->tv_sec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_usec < tv2->tv_usec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return -1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_usec > tv2->tv_usec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 0;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaint timeval_cmp_margin(const struct timeval *tv1, const struct timeval *tv2,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina unsigned int usec_margin)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_sec < tv2->tv_sec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return -1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tv1->tv_sec > tv2->tv_sec)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 1;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if ((tv2->tv_usec - tv1->tv_usec) > (int)usec_margin)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return -1;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if ((tv1->tv_usec - tv2->tv_usec) > (int)usec_margin)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return 1;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekint timeval_diff_msecs(const struct timeval *tv1, const struct timeval *tv2)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return timeval_diff_usecs(tv1, tv2) / 1000;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeklong long timeval_diff_usecs(const struct timeval *tv1,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const struct timeval *tv2)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek time_t secs;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek int usecs;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek secs = tv1->tv_sec - tv2->tv_sec;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek usecs = tv1->tv_usec - tv2->tv_usec;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (usecs < 0) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek secs--;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek usecs += 1000000;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ((long long)secs * 1000000LL) + usecs;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozektime_t time_to_local_day_start(time_t t)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const struct tm *day_tm;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct tm tm;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek time_t new_start_time;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek day_tm = localtime(&t);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek i_zero(&tm);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tm.tm_year = day_tm->tm_year;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tm.tm_mon = day_tm->tm_mon;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tm.tm_mday = day_tm->tm_mday;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tm.tm_isdst = -1;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek new_start_time = mktime(&tm);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek i_assert(new_start_time != (time_t)-1);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return new_start_time;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic const char *strftime_real(const char *fmt, const struct tm *tm)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek size_t bufsize = strlen(fmt) + 32;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char *buf = t_buffer_get(bufsize);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek size_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek while ((ret = strftime(buf, bufsize, fmt, tm)) == 0) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek bufsize *= 2;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek i_assert(bufsize <= STRFTIME_MAX_BUFSIZE);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek buf = t_buffer_get(bufsize);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek t_buffer_alloc(ret + 1);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return buf;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekconst char *t_strftime(const char *fmt, const struct tm *tm)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return strftime_real(fmt, tm);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekconst char *t_strflocaltime(const char *fmt, time_t t)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return strftime_real(fmt, localtime(&t));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekconst char *t_strfgmtime(const char *fmt, time_t t)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return strftime_real(fmt, gmtime(&t));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek