2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula floating point time and date routines -- John Walker
23 * Later double precision integer time/date routines -- Kern Sibbald
28 * Concerning times. There are a number of different time standards
29 * in Bacula (fdate_t, ftime_t, time_t (Unix standard), btime_t, and
30 * utime_t). fdate_t and ftime_t are deprecated and should no longer
31 * be used, and in general, Unix time time_t should no longer be used,
32 * it is being phased out.
34 * Epoch is the base of Unix time in seconds (time_t, ...)
35 * and is 1 Jan 1970 at 0:0 UTC
37 * The major two times that should be left are:
38 * btime_t (64 bit integer in microseconds base Epoch)
39 * utime_t (64 bit integer in seconds base Epoch)
45 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
46 char *bstrftime(char *dt, int maxlen, utime_t utime)
48 time_t time = (time_t)utime;
51 /* ***FIXME**** the format and localtime_r() should be user configurable */
52 (void)localtime_r(&time, &tm);
53 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
57 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
58 char *bstrftimes(char *dt, int maxlen, utime_t utime)
60 time_t time = (time_t)utime;
63 /* ***FIXME**** the format and localtime_r() should be user configurable */
64 (void)localtime_r(&time, &tm);
65 strftime(dt, maxlen, "%d-%b-%Y %H:%M:%S", &tm);
69 /* Formatted time with day name for user display: dd-Mon hh:mm */
70 char *bstrftime_dn(char *dt, int maxlen, utime_t utime)
72 time_t time = (time_t)utime;
75 /* ***FIXME**** the format and localtime_r() should be user configurable */
76 (void)localtime_r(&time, &tm);
77 strftime(dt, maxlen, "%a %d-%b %H:%M", &tm);
81 /* Formatted time (no year) for user display: dd-Mon hh:mm */
82 char *bstrftime_ny(char *dt, int maxlen, utime_t utime)
84 time_t time = (time_t)utime;
87 /* ***FIXME**** the format and localtime_r() should be user configurable */
88 (void)localtime_r(&time, &tm);
89 strftime(dt, maxlen, "%d-%b %H:%M", &tm);
94 /* Formatted time for user display: dd-Mon-yy hh:mm (no century) */
95 char *bstrftime_nc(char *dt, int maxlen, utime_t utime)
97 time_t time = (time_t)utime;
101 /* ***FIXME**** the format and localtime_r() should be user configurable */
102 (void)localtime_r(&time, &tm);
103 /* NOTE! since the compiler complains about %y, I use %y and cut the century */
104 strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
105 /* overlay the century */
116 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
117 char *bstrutime(char *dt, int maxlen, utime_t utime)
119 time_t time = (time_t)utime;
121 (void)localtime_r(&time, &tm);
122 strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
126 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
127 utime_t str_to_utime(char *str)
132 /* Check for bad argument */
133 if (!str || *str == 0) {
137 if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
138 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
146 if (tm.tm_year >= 1900) {
151 tm.tm_wday = tm.tm_yday = 0;
157 return (utime_t)time;
162 * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
163 * the number of microseconds since Epoch Time (1 Jan 1970) UTC.
166 btime_t get_current_btime()
169 if (gettimeofday(&tv, NULL) != 0) {
170 tv.tv_sec = (long)time(NULL); /* fall back to old method */
173 return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
176 /* Convert btime to Unix time */
177 time_t btime_to_unix(btime_t bt)
179 return (time_t)(bt/1000000);
182 /* Convert btime to utime */
183 utime_t btime_to_utime(btime_t bt)
185 return (utime_t)(bt/1000000);
189 * Definition of a leap year from Wikipedia.
190 * I knew it anyway but better check.
192 static bool is_leap_year(int year)
194 if (year % 400 == 0) return true;
195 if (year % 100 == 0) return false;
196 if (year % 4 == 0) return true;
201 * Return the last day of the month, base 0
202 * month=0-11, year is actual year
205 int tm_ldom(int month, int year)
206 { /* jan feb mar apr may jun jul aug sep oct nov dec */
207 static int dom[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
209 if (is_leap_year(year) && month == 1) return 28;
210 return dom[month] - 1;
214 * Return the week of the month, base 0 (wom)
215 * given tm_mday and tm_wday. Value returned
216 * can be from 0 to 5 => week1, ... week6
218 int tm_wom(int mday, int wday)
220 int fs; /* first sunday */
221 fs = (mday%7) - wday;
226 // Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
229 int wom = 1 + (mday - fs - 1) / 7;
230 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
235 * Given a Unix date return the week of the year.
236 * The returned value can be 0-53. Officially
237 * the weeks are numbered from 1 to 53 where week1
238 * is the week in which the first Thursday of the
239 * year occurs (alternatively, the week which contains
240 * the 4th of January). We return 0, if the week of the
241 * year does not fall in the current year.
243 int tm_woy(time_t stime)
245 int woy, fty, tm_yday;
249 memset(&tm, 0, sizeof(struct tm));
250 (void)localtime_r(&stime, &tm);
251 tm_yday = tm.tm_yday;
254 tm.tm_isdst = 0; /* 4 Jan is not DST */
256 (void)localtime_r(&time4, &tm);
257 fty = 1 - tm.tm_wday;
261 woy = tm_yday - fty + 4;
268 /* Deprecated. Do not use. */
269 void get_current_time(struct date_time *dt)
275 (void)gmtime_r(&now, &tm);
276 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,
277 tm.tm_hour, tm.tm_min, tm.tm_sec);
280 Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
282 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,
283 tm.tm_hour, tm.tm_min, tm.tm_sec);
289 /* date_encode -- Encode civil date as a Julian day number. */
290 /* Deprecated. Do not use. */
291 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
294 /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
300 ASSERT(day > 0 && day < 32);
310 /* Determine whether date is in Julian or Gregorian calendar based on
311 canonical date of calendar reform. */
313 if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
316 a = ((int) (y / 100));
320 return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
324 /* time_encode -- Encode time from hours, minutes, and seconds
325 into a fraction of a day. */
327 /* Deprecated. Do not use. */
328 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
329 float32_t second_fraction)
331 ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
332 return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
336 /* date_time_encode -- Set day number and fraction from date
339 /* Deprecated. Do not use. */
340 void date_time_encode(struct date_time *dt,
341 uint32_t year, uint8_t month, uint8_t day,
342 uint8_t hour, uint8_t minute, uint8_t second,
343 float32_t second_fraction)
345 dt->julian_day_number = date_encode(year, month, day);
346 dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
349 /* date_decode -- Decode a Julian day number into civil date. */
351 /* Deprecated. Do not use. */
352 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
355 fdate_t z, f, a, alpha, b, c, d, e;
364 alpha = floor((z - 1867216.25) / 36524.25);
365 a = z + 1 + alpha - floor(alpha / 4);
369 c = floor((b - 122.1) / 365.25);
370 d = floor(365.25 * c);
371 e = floor((b - d) / 30.6001);
373 *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
374 *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
375 *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
378 /* time_decode -- Decode a day fraction into civil time. */
380 /* Deprecated. Do not use. */
381 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
382 uint8_t *second, float32_t *second_fraction)
386 ij = (uint32_t) ((time - floor(time)) * 86400.0);
387 *hour = (uint8_t) (ij / 3600L);
388 *minute = (uint8_t) ((ij / 60L) % 60L);
389 *second = (uint8_t) (ij % 60L);
390 if (second_fraction != NULL) {
391 *second_fraction = (float32_t)(time - floor(time));
395 /* date_time_decode -- Decode a Julian day and day fraction
396 into civil date and time. */
398 /* Deprecated. Do not use. */
399 void date_time_decode(struct date_time *dt,
400 uint32_t *year, uint8_t *month, uint8_t *day,
401 uint8_t *hour, uint8_t *minute, uint8_t *second,
402 float32_t *second_fraction)
404 date_decode(dt->julian_day_number, year, month, day);
405 time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
408 /* tm_encode -- Encode a civil date and time from a tm structure
409 * to a Julian day and day fraction.
412 /* Deprecated. Do not use. */
413 void tm_encode(struct date_time *dt,
417 uint8_t month, day, hour, minute, second;
419 year = tm->tm_year + 1900;
420 month = tm->tm_mon + 1;
425 dt->julian_day_number = date_encode(year, month, day);
426 dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
430 /* tm_decode -- Decode a Julian day and day fraction
431 into civil date and time in tm structure */
433 /* Deprecated. Do not use. */
434 void tm_decode(struct date_time *dt,
438 uint8_t month, day, hour, minute, second;
440 date_decode(dt->julian_day_number, &year, &month, &day);
441 time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
442 tm->tm_year = year - 1900;
443 tm->tm_mon = month - 1;
451 /* date_time_compare -- Compare two dates and times and return
452 the relationship as follows:
459 /* Deprecated. Do not use. */
460 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
462 if (dt1->julian_day_number == dt2->julian_day_number) {
463 if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
466 return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
468 return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;