2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many 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 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Bacula floating point time and date routines -- John Walker
22 * Later double precision integer time/date routines -- Kern Sibbald
27 * Concerning times. There are a number of different time standards
28 * in Bacula (fdate_t, ftime_t, time_t (Unix standard), btime_t, and
29 * utime_t). fdate_t and ftime_t are deprecated and should no longer
30 * be used, and in general, Unix time time_t should no longer be used,
31 * it is being phased out.
33 * Epoch is the base of Unix time in seconds (time_t, ...)
34 * and is 1 Jan 1970 at 0:0 UTC
36 * The major two times that should be left are:
37 * btime_t (64 bit integer in microseconds base Epoch)
38 * utime_t (64 bit integer in seconds base Epoch)
44 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
45 char *bstrftime(char *dt, int maxlen, utime_t utime)
47 time_t time = (time_t)utime;
50 /* ***FIXME**** the format and localtime_r() should be user configurable */
51 (void)localtime_r(&time, &tm);
52 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
56 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
57 char *bstrftimes(char *dt, int maxlen, utime_t utime)
59 time_t time = (time_t)utime;
62 /* ***FIXME**** the format and localtime_r() should be user configurable */
63 (void)localtime_r(&time, &tm);
64 strftime(dt, maxlen, "%d-%b-%Y %H:%M:%S", &tm);
68 /* Formatted time with day name for user display: dd-Mon hh:mm */
69 char *bstrftime_dn(char *dt, int maxlen, utime_t utime)
71 time_t time = (time_t)utime;
74 /* ***FIXME**** the format and localtime_r() should be user configurable */
75 (void)localtime_r(&time, &tm);
76 strftime(dt, maxlen, "%a %d-%b %H:%M", &tm);
80 /* Formatted time (no year) for user display: dd-Mon hh:mm */
81 char *bstrftime_ny(char *dt, int maxlen, utime_t utime)
83 time_t time = (time_t)utime;
86 /* ***FIXME**** the format and localtime_r() should be user configurable */
87 (void)localtime_r(&time, &tm);
88 strftime(dt, maxlen, "%d-%b %H:%M", &tm);
93 /* Formatted time for user display: dd-Mon-yy hh:mm (no century) */
94 char *bstrftime_nc(char *dt, int maxlen, utime_t utime)
96 time_t time = (time_t)utime;
100 /* ***FIXME**** the format and localtime_r() should be user configurable */
101 (void)localtime_r(&time, &tm);
102 /* NOTE! since the compiler complains about %y, I use %y and cut the century */
103 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
104 /* overlay the century */
115 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
116 char *bstrutime(char *dt, int maxlen, utime_t utime)
118 time_t time = (time_t)utime;
120 (void)localtime_r(&time, &tm);
121 strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
125 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
126 utime_t str_to_utime(char *str)
131 /* Check for bad argument */
132 if (!str || *str == 0) {
136 if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
137 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
145 if (tm.tm_year >= 1900) {
150 tm.tm_wday = tm.tm_yday = 0;
156 return (utime_t)time;
161 * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
162 * the number of microseconds since Epoch Time (1 Jan 1970) UTC.
165 btime_t get_current_btime()
168 if (gettimeofday(&tv, NULL) != 0) {
169 tv.tv_sec = (long)time(NULL); /* fall back to old method */
172 return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
175 /* Convert btime to Unix time */
176 time_t btime_to_unix(btime_t bt)
178 return (time_t)(bt/1000000);
181 /* Convert btime to utime */
182 utime_t btime_to_utime(btime_t bt)
184 return (utime_t)(bt/1000000);
188 * Definition of a leap year from Wikipedia.
189 * I knew it anyway but better check.
191 static bool is_leap_year(int year)
193 if (year % 400 == 0) return true;
194 if (year % 100 == 0) return false;
195 if (year % 4 == 0) return true;
200 * Return the last day of the month, base 0
201 * month=0-11, year is actual year
204 int tm_ldom(int month, int year)
205 { /* jan feb mar apr may jun jul aug sep oct nov dec */
206 static int dom[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
208 if (is_leap_year(year) && month == 1) return 28;
209 return dom[month] - 1;
213 * Return the week of the month, base 0 (wom)
214 * given tm_mday and tm_wday. Value returned
215 * can be from 0 to 5 => week1, ... week6
217 int tm_wom(int mday, int wday)
219 int fs; /* first sunday */
220 fs = (mday%7) - wday;
225 // Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
228 int wom = 1 + (mday - fs - 1) / 7;
229 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
234 * Given a Unix date return the week of the year.
235 * The returned value can be 0-53. Officially
236 * the weeks are numbered from 1 to 53 where week1
237 * is the week in which the first Thursday of the
238 * year occurs (alternatively, the week which contains
239 * the 4th of January). We return 0, if the week of the
240 * year does not fall in the current year.
242 int tm_woy(time_t stime)
244 int woy, fty, tm_yday;
248 memset(&tm, 0, sizeof(struct tm));
249 (void)localtime_r(&stime, &tm);
250 tm_yday = tm.tm_yday;
253 tm.tm_isdst = 0; /* 4 Jan is not DST */
255 (void)localtime_r(&time4, &tm);
256 fty = 1 - tm.tm_wday;
260 woy = tm_yday - fty + 4;
267 /* Deprecated. Do not use. */
268 void get_current_time(struct date_time *dt)
274 (void)gmtime_r(&now, &tm);
275 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,
276 tm.tm_hour, tm.tm_min, tm.tm_sec);
279 Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
281 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,
282 tm.tm_hour, tm.tm_min, tm.tm_sec);
288 /* date_encode -- Encode civil date as a Julian day number. */
289 /* Deprecated. Do not use. */
290 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
293 /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
299 ASSERT(day > 0 && day < 32);
309 /* Determine whether date is in Julian or Gregorian calendar based on
310 canonical date of calendar reform. */
312 if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
315 a = ((int) (y / 100));
319 return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
323 /* time_encode -- Encode time from hours, minutes, and seconds
324 into a fraction of a day. */
326 /* Deprecated. Do not use. */
327 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
328 float32_t second_fraction)
330 ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
331 return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
335 /* date_time_encode -- Set day number and fraction from date
338 /* Deprecated. Do not use. */
339 void date_time_encode(struct date_time *dt,
340 uint32_t year, uint8_t month, uint8_t day,
341 uint8_t hour, uint8_t minute, uint8_t second,
342 float32_t second_fraction)
344 dt->julian_day_number = date_encode(year, month, day);
345 dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
348 /* date_decode -- Decode a Julian day number into civil date. */
350 /* Deprecated. Do not use. */
351 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
354 fdate_t z, f, a, alpha, b, c, d, e;
363 alpha = floor((z - 1867216.25) / 36524.25);
364 a = z + 1 + alpha - floor(alpha / 4);
368 c = floor((b - 122.1) / 365.25);
369 d = floor(365.25 * c);
370 e = floor((b - d) / 30.6001);
372 *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
373 *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
374 *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
377 /* time_decode -- Decode a day fraction into civil time. */
379 /* Deprecated. Do not use. */
380 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
381 uint8_t *second, float32_t *second_fraction)
385 ij = (uint32_t) ((time - floor(time)) * 86400.0);
386 *hour = (uint8_t) (ij / 3600L);
387 *minute = (uint8_t) ((ij / 60L) % 60L);
388 *second = (uint8_t) (ij % 60L);
389 if (second_fraction != NULL) {
390 *second_fraction = (float32_t)(time - floor(time));
394 /* date_time_decode -- Decode a Julian day and day fraction
395 into civil date and time. */
397 /* Deprecated. Do not use. */
398 void date_time_decode(struct date_time *dt,
399 uint32_t *year, uint8_t *month, uint8_t *day,
400 uint8_t *hour, uint8_t *minute, uint8_t *second,
401 float32_t *second_fraction)
403 date_decode(dt->julian_day_number, year, month, day);
404 time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
407 /* tm_encode -- Encode a civil date and time from a tm structure
408 * to a Julian day and day fraction.
411 /* Deprecated. Do not use. */
412 void tm_encode(struct date_time *dt,
416 uint8_t month, day, hour, minute, second;
418 year = tm->tm_year + 1900;
419 month = tm->tm_mon + 1;
424 dt->julian_day_number = date_encode(year, month, day);
425 dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
429 /* tm_decode -- Decode a Julian day and day fraction
430 into civil date and time in tm structure */
432 /* Deprecated. Do not use. */
433 void tm_decode(struct date_time *dt,
437 uint8_t month, day, hour, minute, second;
439 date_decode(dt->julian_day_number, &year, &month, &day);
440 time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
441 tm->tm_year = year - 1900;
442 tm->tm_mon = month - 1;
450 /* date_time_compare -- Compare two dates and times and return
451 the relationship as follows:
458 /* Deprecated. Do not use. */
459 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
461 if (dt1->julian_day_number == dt2->julian_day_number) {
462 if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
465 return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
467 return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;