]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/timeutils: add strxxx_iso() functions
authorKarel Zak <kzak@redhat.com>
Wed, 11 May 2016 13:31:02 +0000 (15:31 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 11 May 2016 13:31:02 +0000 (15:31 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/strutils.h
include/timeutils.h
lib/Makemodule.am
lib/strutils.c
lib/timeutils.c

index 9f4339f41e21dc6268f848c5e9e673a64d1947bf..f303450f51e23bd38d3d78cc18053156d62d74a1 100644 (file)
@@ -212,6 +212,8 @@ static inline size_t ltrim_whitespace(unsigned char *str)
 
 extern char *strnappend(const char *s, const char *suffix, size_t b);
 extern char *strappend(const char *s, const char *suffix);
+extern char *strfappend(const char *s, const char *format, ...)
+                __attribute__ ((__format__ (__printf__, 2, 0)));
 extern const char *split(const char **state, size_t *l, const char *separator, int quoted);
 
 extern int skip_fline(FILE *fp);
index 8ed501b9dbb07eef236abde38f757a947c426cff..4b6098ae15338e981218dfe415ee95fe5243a9b0 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <stdio.h>
 #include <inttypes.h>
+#include <sys/time.h>
 
 typedef uint64_t usec_t;
 typedef uint64_t nsec_t;
@@ -53,4 +54,16 @@ typedef uint64_t nsec_t;
 
 int parse_timestamp(const char *t, usec_t *usec);
 
+/* flags for strxxx_iso() functions */
+enum {
+       ISO_8601_DATE           = (1 << 1),
+       ISO_8601_TIME           = (1 << 2),
+       ISO_8601_USEC           = (1 << 3),
+       ISO_8601_TIMEZONE       = (1 << 4),
+       ISO_8601_SPACE          = (1 << 5)
+};
+char *strtimeval_iso(struct timeval *tv, int flags);
+char *strtm_iso(struct tm *tm, int flags);
+char *strtime_iso(time_t t, int flags);
+
 #endif /* UTIL_LINUX_TIME_UTIL_H */
index 054b81628985d8ade9d23f257c0ba0aa07ac07ae..092d54e7453063ff532c28704c64a4a0c5a84390 100644 (file)
@@ -60,7 +60,8 @@ check_PROGRAMS += \
        test_mangle \
        test_randutils \
        test_strutils \
-       test_ttyutils
+       test_ttyutils \
+       test_timeutils
 
 
 
@@ -125,3 +126,5 @@ test_fileutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM
 test_canonicalize_SOURCES = lib/canonicalize.c
 test_canonicalize_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_CANONICALIZE
 
+test_timeutils_SOURCES = lib/timeutils.c lib/strutils.c
+test_timeutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_TIMEUTILS
index 5a6be2daed3db3a0369db87b884cb42aa087178b..d5bb2db1331189083b2014d933d08d7d6351522a 100644 (file)
@@ -816,6 +816,23 @@ char *strappend(const char *s, const char *suffix)
         return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
 }
 
+char *strfappend(const char *s, const char *format, ...)
+{
+       va_list ap;
+       char *val, *res;
+       int sz;
+
+       va_start(ap, format);
+       sz = vasprintf(&val, format, ap);
+       va_end(ap);
+
+       if (sz < 0)
+               return NULL;
+
+       res = strnappend(s, val, sz);
+       free(val);
+       return res;
+}
 
 static size_t strcspn_escaped(const char *s, const char *reject)
 {
index 854ef6915fed73df31cb59167d393c3c2e8bcb23..c291043ede10cc8d09b77ba7a32a8b9222370e34 100644 (file)
@@ -338,3 +338,84 @@ int parse_timestamp(const char *t, usec_t *usec)
 
        return 0;
 }
+
+static char *format_iso_time(struct tm *tm, suseconds_t usec, int flags)
+{
+       char *s = NULL;
+
+       if (flags & ISO_8601_DATE)
+               s = strfappend(s, "%4d-%.2d-%.2d", tm->tm_year + 1900,
+                                               tm->tm_mon + 1, tm->tm_mday);
+       if ((flags & ISO_8601_DATE) && (flags & ISO_8601_TIME))
+               s = strnappend(s, (flags & ISO_8601_SPACE) ? " " : "T", 1);
+
+       if (flags & ISO_8601_TIME)
+               s = strfappend(s, "%02d:%02d:%02d", tm->tm_hour,
+                                                tm->tm_min, tm->tm_sec);
+       if (flags & ISO_8601_USEC)
+               s = strfappend(s, ".%06ld", (long) usec);
+
+       if (flags & ISO_8601_TIMEZONE) {
+               int zhour = - timezone / 60 / 60;
+               int zmin = labs(timezone / 60 % 60);
+
+               s = strfappend(s, "%+02d:%02d", zhour, zmin);
+       }
+
+       return s;
+}
+
+char *strtimeval_iso(struct timeval *tv, int flags)
+{
+       struct tm tm = *localtime(&tv->tv_sec);
+       return format_iso_time(&tm, tv->tv_usec, flags);
+}
+
+char *strtm_iso(struct tm *tm, int flags)
+{
+       return format_iso_time(tm, 0, flags);
+}
+
+char *strtime_iso(time_t t, int flags)
+{
+       struct tm tm = *localtime(&t);
+       return format_iso_time(&tm, 0, flags);
+}
+
+
+#ifdef TEST_PROGRAM_TIMEUTILS
+
+int main(int argc, char *argv[])
+{
+       struct timeval tv = { 0 };
+       char *p;
+
+       if (argc < 2) {
+               fprintf(stderr, "usage: %s <time> [<usec>]\n", argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       tv.tv_sec = strtos64_or_err(argv[1], "failed to parse <time>");
+       if (argc == 3)
+               tv.tv_usec = strtos64_or_err(argv[2], "failed to parse <usec>");
+
+       p = strtimeval_iso(&tv, ISO_8601_DATE);
+       printf("Date: '%s'\n", p);
+       free(p);
+
+       p = strtimeval_iso(&tv, ISO_8601_TIME);
+       printf("Time: '%s'\n", p);
+       free(p);
+
+       p = strtimeval_iso(&tv, ISO_8601_DATE | ISO_8601_TIME | ISO_8601_USEC);
+       printf("Full: '%s'\n", p);
+       free(p);
+
+       p = strtimeval_iso(&tv, ISO_8601_DATE | ISO_8601_TIME | ISO_8601_USEC | ISO_8601_TIMEZONE | ISO_8601_SPACE);
+       printf("Zone: '%s'\n", p);
+       free(p);
+
+       return EXIT_SUCCESS;
+}
+
+#endif /* TEST_PROGRAM */