2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
17 * Bacula floating point time and date routines -- John Walker
19 * Later double precision integer time/date routines -- Kern Sibbald
24 * Concerning times. There are a number of different time standards
25 * in Bacula (fdate_t, ftime_t, time_t (Unix standard), btime_t, and
26 * utime_t). fdate_t and ftime_t are deprecated and should no longer
27 * be used, and in general, Unix time time_t should no longer be used,
28 * it is being phased out.
30 * Epoch is the base of Unix time in seconds (time_t, ...)
31 * and is 1 Jan 1970 at 0:0 UTC
33 * The major two times that should be left are:
34 * btime_t (64 bit integer in microseconds base Epoch)
35 * utime_t (64 bit integer in seconds base Epoch)
41 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
42 char *bstrftime(char *dt, int maxlen, utime_t utime)
44 time_t time = (time_t)utime;
47 /* ***FIXME**** the format and localtime_r() should be user configurable */
48 (void)localtime_r(&time, &tm);
49 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
53 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
54 char *bstrftimes(char *dt, int maxlen, utime_t utime)
56 time_t time = (time_t)utime;
59 /* ***FIXME**** the format and localtime_r() should be user configurable */
60 (void)localtime_r(&time, &tm);
61 strftime(dt, maxlen, "%d-%b-%Y %H:%M:%S", &tm);
65 /* Formatted time with day name for user display: dd-Mon hh:mm */
66 char *bstrftime_dn(char *dt, int maxlen, utime_t utime)
68 time_t time = (time_t)utime;
71 /* ***FIXME**** the format and localtime_r() should be user configurable */
72 (void)localtime_r(&time, &tm);
73 strftime(dt, maxlen, "%a %d-%b %H:%M", &tm);
77 /* Formatted time (no year) for user display: dd-Mon hh:mm */
78 char *bstrftime_ny(char *dt, int maxlen, utime_t utime)
80 time_t time = (time_t)utime;
83 /* ***FIXME**** the format and localtime_r() should be user configurable */
84 (void)localtime_r(&time, &tm);
85 strftime(dt, maxlen, "%d-%b %H:%M", &tm);
90 /* Formatted time for user display: dd-Mon-yy hh:mm (no century) */
91 char *bstrftime_nc(char *dt, int maxlen, utime_t utime)
93 time_t time = (time_t)utime;
97 /* ***FIXME**** the format and localtime_r() should be user configurable */
98 (void)localtime_r(&time, &tm);
99 /* NOTE! since the compiler complains about %y, I use %y and cut the century */
100 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
101 /* overlay the century */
112 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
113 char *bstrutime(char *dt, int maxlen, utime_t utime)
115 time_t time = (time_t)utime;
117 (void)localtime_r(&time, &tm);
118 strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
122 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
123 utime_t str_to_utime(char *str)
128 /* Check for bad argument */
129 if (!str || *str == 0) {
133 if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
134 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
142 if (tm.tm_year >= 1900) {
147 tm.tm_wday = tm.tm_yday = 0;
153 return (utime_t)time;
158 * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
159 * the number of microseconds since Epoch Time (1 Jan 1970) UTC.
162 btime_t get_current_btime()
165 if (gettimeofday(&tv, NULL) != 0) {
166 tv.tv_sec = (long)time(NULL); /* fall back to old method */
169 return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
172 /* Convert btime to Unix time */
173 time_t btime_to_unix(btime_t bt)
175 return (time_t)(bt/1000000);
178 /* Convert btime to utime */
179 utime_t btime_to_utime(btime_t bt)
181 return (utime_t)(bt/1000000);
185 * Definition of a leap year from Wikipedia.
186 * I knew it anyway but better check.
188 static bool is_leap_year(int year)
190 if (year % 400 == 0) return true;
191 if (year % 100 == 0) return false;
192 if (year % 4 == 0) return true;
197 * Return the last day of the month, base 0
198 * month=0-11, year is actual year
201 int tm_ldom(int month, int year)
202 { /* jan feb mar apr may jun jul aug sep oct nov dec */
203 static int dom[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
205 if (is_leap_year(year) && month == 1) return 28;
206 return dom[month] - 1;
210 * Return the week of the month, base 0 (wom)
211 * given tm_mday and tm_wday. Value returned
212 * can be from 0 to 5 => week1, ... week6
214 int tm_wom(int mday, int wday)
216 int fs; /* first sunday */
217 fs = (mday%7) - wday;
222 // Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
225 int wom = 1 + (mday - fs - 1) / 7;
226 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
231 * Given a Unix date return the week of the year.
232 * The returned value can be 0-53. Officially
233 * the weeks are numbered from 1 to 53 where week1
234 * is the week in which the first Thursday of the
235 * year occurs (alternatively, the week which contains
236 * the 4th of January). We return 0, if the week of the
237 * year does not fall in the current year.
239 int tm_woy(time_t stime)
241 int woy, fty, tm_yday;
245 memset(&tm, 0, sizeof(struct tm));
246 (void)localtime_r(&stime, &tm);
247 tm_yday = tm.tm_yday;
250 tm.tm_isdst = 0; /* 4 Jan is not DST */
252 (void)localtime_r(&time4, &tm);
253 fty = 1 - tm.tm_wday;
257 woy = tm_yday - fty + 4;
264 /* Deprecated. Do not use. */
265 void get_current_time(struct date_time *dt)
271 (void)gmtime_r(&now, &tm);
272 Dmsg6(200, "m=%d d=%d y=%d h=%d m=%d s=%d\n", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900,
273 tm.tm_hour, tm.tm_min, tm.tm_sec);
276 Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
278 Dmsg6(200, "m=%d d=%d y=%d h=%d m=%d s=%d\n", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900,
279 tm.tm_hour, tm.tm_min, tm.tm_sec);
285 /* date_encode -- Encode civil date as a Julian day number. */
286 /* Deprecated. Do not use. */
287 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
290 /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
296 ASSERT(day > 0 && day < 32);
306 /* Determine whether date is in Julian or Gregorian calendar based on
307 canonical date of calendar reform. */
309 if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
312 a = ((int) (y / 100));
316 return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
320 /* time_encode -- Encode time from hours, minutes, and seconds
321 into a fraction of a day. */
323 /* Deprecated. Do not use. */
324 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
325 float32_t second_fraction)
327 ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
328 return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
332 /* date_time_encode -- Set day number and fraction from date
335 /* Deprecated. Do not use. */
336 void date_time_encode(struct date_time *dt,
337 uint32_t year, uint8_t month, uint8_t day,
338 uint8_t hour, uint8_t minute, uint8_t second,
339 float32_t second_fraction)
341 dt->julian_day_number = date_encode(year, month, day);
342 dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
345 /* date_decode -- Decode a Julian day number into civil date. */
347 /* Deprecated. Do not use. */
348 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
351 fdate_t z, f, a, alpha, b, c, d, e;
360 alpha = floor((z - 1867216.25) / 36524.25);
361 a = z + 1 + alpha - floor(alpha / 4);
365 c = floor((b - 122.1) / 365.25);
366 d = floor(365.25 * c);
367 e = floor((b - d) / 30.6001);
369 *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
370 *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
371 *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
374 /* time_decode -- Decode a day fraction into civil time. */
376 /* Deprecated. Do not use. */
377 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
378 uint8_t *second, float32_t *second_fraction)
382 ij = (uint32_t) ((time - floor(time)) * 86400.0);
383 *hour = (uint8_t) (ij / 3600L);
384 *minute = (uint8_t) ((ij / 60L) % 60L);
385 *second = (uint8_t) (ij % 60L);
386 if (second_fraction != NULL) {
387 *second_fraction = (float32_t)(time - floor(time));
391 /* date_time_decode -- Decode a Julian day and day fraction
392 into civil date and time. */
394 /* Deprecated. Do not use. */
395 void date_time_decode(struct date_time *dt,
396 uint32_t *year, uint8_t *month, uint8_t *day,
397 uint8_t *hour, uint8_t *minute, uint8_t *second,
398 float32_t *second_fraction)
400 date_decode(dt->julian_day_number, year, month, day);
401 time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
404 /* tm_encode -- Encode a civil date and time from a tm structure
405 * to a Julian day and day fraction.
408 /* Deprecated. Do not use. */
409 void tm_encode(struct date_time *dt,
413 uint8_t month, day, hour, minute, second;
415 year = tm->tm_year + 1900;
416 month = tm->tm_mon + 1;
421 dt->julian_day_number = date_encode(year, month, day);
422 dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
426 /* tm_decode -- Decode a Julian day and day fraction
427 into civil date and time in tm structure */
429 /* Deprecated. Do not use. */
430 void tm_decode(struct date_time *dt,
434 uint8_t month, day, hour, minute, second;
436 date_decode(dt->julian_day_number, &year, &month, &day);
437 time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
438 tm->tm_year = year - 1900;
439 tm->tm_mon = month - 1;
447 /* date_time_compare -- Compare two dates and times and return
448 the relationship as follows:
455 /* Deprecated. Do not use. */
456 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
458 if (dt1->julian_day_number == dt2->julian_day_number) {
459 if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
462 return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
464 return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;