8113bb5e495f45180faa4194870c289aa1958726
[obnox/samba/samba-obnox.git] / lib / util / time_basic.c
1 /*
2  * Unix SMB/CIFS implementation.
3  * time handling functions
4  *
5  * Copyright (C) Andrew Tridgell                1992-2004
6  * Copyright (C) Stefan (metze) Metzmacher      2002
7  * Copyright (C) Jeremy Allison                 2007
8  * Copyright (C) Andrew Bartlett                2011
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "replace.h"
25 #include "lib/util/time_basic.h"
26
27 /**
28 a gettimeofday wrapper
29 **/
30 _PUBLIC_ void GetTimeOfDay(struct timeval *tval)
31 {
32 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
33         gettimeofday(tval,NULL);
34 #else
35         gettimeofday(tval);
36 #endif
37 }
38
39 /****************************************************************************
40  Return the date and time as a string
41 ****************************************************************************/
42
43 char *timeval_str_buf(const struct timeval *tp, bool rfc5424, bool hires,
44                       struct timeval_buf *dst)
45 {
46         time_t t;
47         struct tm *tm;
48         size_t len;
49
50         t = (time_t)tp->tv_sec;
51         tm = localtime(&t);
52
53         if (tm == NULL) {
54                 if (hires) {
55                         snprintf(dst->buf, sizeof(dst->buf),
56                                  "%ld.%06ld seconds since the Epoch",
57                                  (long)tp->tv_sec, (long)tp->tv_usec);
58                 } else {
59                         snprintf(dst->buf, sizeof(dst->buf),
60                                  "%ld seconds since the Epoch", (long)t);
61                 }
62                 return dst->buf;
63         }
64
65         len = snprintf(dst->buf, sizeof(dst->buf),
66                        (rfc5424 ?
67                         "%04d-%02d-%02dT%02d:%02d:%02d" :
68                         "%04d/%02d/%02d %02d:%02d:%02d"),
69                        1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
70                        tm->tm_hour, tm->tm_min, tm->tm_sec);
71
72         if ((rfc5424 || hires) && (len < sizeof(dst->buf))) {
73                 len += snprintf(dst->buf + len, sizeof(dst->buf) - len,
74                                 ".%06ld", (long)tp->tv_usec);
75         }
76
77         if (rfc5424 && (len < sizeof(dst->buf))) {
78                 struct tm tm_utc, tm_local;
79                 int offset;
80
81                 tm_local = *tm;
82                 /* It is reasonable to assume that if localtime()
83                  * worked above, then gmtime() should also work
84                  * without error. */
85                 tm_utc = *gmtime(&t);
86
87                 offset = (tm_local.tm_hour - tm_utc.tm_hour) * 60 +
88                         (tm_local.tm_min - tm_utc.tm_min);
89
90                 snprintf(dst->buf + len, sizeof(dst->buf) - len,
91                          "%c%02d:%02d",
92                          (offset >=0 ? '+' : '-'),
93                          abs(offset) / 60,
94                          abs(offset) % 60);
95         }
96
97         return dst->buf;
98 }