qLibc
qtime.c
Go to the documentation of this file.
1/******************************************************************************
2 * qLibc
3 *
4 * Copyright (c) 2010-2026 Seungyoung Kim.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *****************************************************************************/
28
29/**
30 * @file qtime.c Time handling APIs.
31 */
32
33#define __USE_XOPEN
34#define _XOPEN_SOURCE
35#define _BSD_SOURCE
36#include <stdio.h>
37#include <stdlib.h>
38#include <stdbool.h>
39#include <string.h>
40#include <sys/time.h>
41#include "qinternal.h"
42#include "utilities/qtime.h"
43
44/**
45 * Returns the current time in milliseconds.
46 *
47 * @return current time in milliseconds.
48 */
50 struct timeval tv;
51 gettimeofday(&tv, NULL);
52 long time = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
53 return time;
54}
55
56/**
57 * Format a local time string with a custom format.
58 *
59 * @param buf output buffer
60 * @param size buffer size
61 * @param utctime 0 for the current time, or a specific UTC time
62 * @param format format string for `strftime()`
63 *
64 * @return pointer to `buf`
65 *
66 * @code
67 * char *timestr = qtime_localtime_strf(0, "%H:%M:%S"); // HH:MM:SS
68 * free(timestr);
69 * char *timestr = qtime_localtime_strf(0, "%Y%m%d%H%M%S"); // YYMMDDhhmmss
70 * free(timestr);
71 * @endcode
72 */
73char *qtime_localtime_strf(char *buf, int size, time_t utctime,
74 const char *format) {
75 if (utctime == 0)
76 utctime = time(NULL);
77 struct tm *localtm = localtime(&utctime);
78
79 if (strftime(buf, size, format, localtm) == 0) {
80 snprintf(buf, size, "(buffer small)");
81 }
82
83 return buf;
84}
85
86/**
87 * Get local time string formatted like '02-Nov-2007 16:37:39 +0900'.
88 *
89 * @param utctime 0 for the current time, or a specific UTC time
90 *
91 * @return allocated time string.
92 *
93 * @code
94 * char *timestr;
95 * timestr = qtime_localtime_str(0); // now
96 * free(timestr);
97 * timestr = qtime_localtime_str(time(NULL)); // same as above
98 * free(timestr);
99 * timestr = qtime_localtime_str(time(NULL) - 86400)); // 1 day before
100 * free(timestr);
101 * @endcode
102 */
103char *qtime_localtime_str(time_t utctime) {
104 int size = sizeof(char) * (CONST_STRLEN("00-Jan-0000 00:00:00 +0000") + 1);
105 char *timestr = (char *) malloc(size);
106 if (timestr == NULL)
107 return NULL;
108
109 qtime_localtime_strf(timestr, size, utctime, "%d-%b-%Y %H:%M:%S %z");
110 return timestr;
111}
112
113/**
114 * Get local time string formatted like '02-Nov-2007 16:37:39 +0900'.
115 *
116 * @param utctime 0 for the current time, or a specific UTC time
117 *
118 * @return internal static time string.
119 *
120 * @code
121 * printf("%s", qtime_localtime_staticstr(0)); // now
122 * printf("%s", qtime_localtime_staticstr(time(NULL) + 86400)); // 1 day later
123 * @endcode
124 */
125const char *qtime_localtime_staticstr(time_t utctime) {
126 static char timestr[sizeof(char)
127 * (CONST_STRLEN("00-Jan-0000 00:00:00 +0000") + 1)];
128 qtime_localtime_strf(timestr, sizeof(timestr), utctime,
129 "%d-%b-%Y %H:%M:%S %z");
130 return timestr;
131}
132
133/**
134 * Format a GMT time string with a custom format.
135 *
136 * @param buf output buffer
137 * @param size buffer size
138 * @param utctime 0 for the current time, or a specific UTC time
139 * @param format format string for `strftime()`
140 *
141 * @return pointer to `buf`
142 *
143 * @code
144 * char timestr[8+1];
145 * qtime_gmt_strf(buf, sizeof(buf), 0, "%H:%M:%S"); // HH:MM:SS
146 * @endcode
147 */
148char *qtime_gmt_strf(char *buf, int size, time_t utctime, const char *format) {
149 if (utctime == 0)
150 utctime = time(NULL);
151 struct tm *gmtm = gmtime(&utctime);
152
153 strftime(buf, size, format, gmtm);
154 return buf;
155}
156
157/**
158 * Get GMT time string formatted like 'Wed, 11-Nov-2007 23:19:25 GMT'.
159 *
160 * @param utctime 0 for the current time, or a specific UTC time
161 *
162 * @return allocated GMT time string.
163 *
164 * @code
165 * char *timestr;
166 * timestr = qtime_gmt_str(0); // now
167 * free(timestr);
168 * timestr = qtime_gmt_str(time(NULL)); // same as above
169 * free(timestr);
170 * timestr = qtime_gmt_str(time(NULL) - 86400)); // 1 day before
171 * free(timestr);
172 * @endcode
173 */
174char *qtime_gmt_str(time_t utctime) {
175 int size = sizeof(char)
176 * (CONST_STRLEN("Mon, 00 Jan 0000 00:00:00 GMT") + 1);
177 char *timestr = (char *) malloc(size);
178 if (timestr == NULL)
179 return NULL;
180
181 qtime_gmt_strf(timestr, size, utctime, "%a, %d %b %Y %H:%M:%S GMT");
182 return timestr;
183}
184
185/**
186 * Get GMT time string formatted like 'Wed, 11-Nov-2007 23:19:25 GMT'.
187 *
188 * @param utctime 0 for the current time, or a specific UTC time
189 *
190 * @return internal static GMT time string.
191 *
192 * @code
193 * printf("%s", qtime_gmt_staticstr(0)); // now
194 * printf("%s", qtime_gmt_staticstr(time(NULL) + 86400)); // 1 day later
195 * @endcode
196 */
197const char *qtime_gmt_staticstr(time_t utctime) {
198 static char timestr[sizeof(char)
199 * (CONST_STRLEN("Mon, 00-Jan-0000 00:00:00 GMT") + 1)];
200 qtime_gmt_strf(timestr, sizeof(timestr), utctime,
201 "%a, %d %b %Y %H:%M:%S GMT");
202 return timestr;
203}
204
205/**
206 * Parse a GMT or timezone-formatted time string and return UTC time.
207 *
208 * Examples:
209 * 'Sun, 04 May 2008 18:50:39 GMT'
210 * 'Mon, 05 May 2008 03:50:39 +0900'
211 *
212 * @param gmtstr GMT/timezone-formatted time string
213 *
214 * @return UTC time. Returns -1 on conversion error.
215 *
216 * @code
217 * time_t t = time(NULL);
218 * char *s = qtime_parse_gmtstr(t);
219 * printf("%d\n", t);
220 * printf("%s\n", s);
221 * printf("%d\n", qtime_parse_gmtstr(s)); // this must be same as t
222 * free(s);
223 * @endcode
224 */
225time_t qtime_parse_gmtstr(const char *gmtstr) {
226 struct tm gmtm;
227 if (strptime(gmtstr, "%a, %d %b %Y %H:%M:%S", &gmtm) == NULL)
228 return 0;
229 time_t utc = timegm(&gmtm);
230 if (utc < 0)
231 return -1;
232
233// Parse timezone.
234 char *p;
235 if ((p = strstr(gmtstr, "+")) != NULL) {
236 utc -= ((atoi(p + 1) / 100) * 60 * 60);
237 if (utc < 0)
238 return -1;
239 } else if ((p = strstr(gmtstr, "-")) != NULL) {
240 utc += ((atoi(p + 1) / 100) * 60 * 60);
241 }
242
243 return utc;
244}
char * qtime_gmt_strf(char *buf, int size, time_t utctime, const char *format)
Format a GMT time string with a custom format.
Definition qtime.c:148
char * qtime_gmt_str(time_t utctime)
Get GMT time string formatted like 'Wed, 11-Nov-2007 23:19:25 GMT'.
Definition qtime.c:174
char * qtime_localtime_str(time_t utctime)
Get local time string formatted like '02-Nov-2007 16:37:39 +0900'.
Definition qtime.c:103
long qtime_current_milli(void)
Returns the current time in milliseconds.
Definition qtime.c:49
time_t qtime_parse_gmtstr(const char *gmtstr)
Parse a GMT or timezone-formatted time string and return UTC time.
Definition qtime.c:225
char * qtime_localtime_strf(char *buf, int size, time_t utctime, const char *format)
Format a local time string with a custom format.
Definition qtime.c:73
const char * qtime_gmt_staticstr(time_t utctime)
Get GMT time string formatted like 'Wed, 11-Nov-2007 23:19:25 GMT'.
Definition qtime.c:197
const char * qtime_localtime_staticstr(time_t utctime)
Get local time string formatted like '02-Nov-2007 16:37:39 +0900'.
Definition qtime.c:125