]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/btime.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / lib / btime.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6
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.
9
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.
14
15    This notice must be preserved when any source code is 
16    conveyed and/or propagated.
17
18    Bacula(R) is a registered trademark of Kern Sibbald.
19 */
20 /*
21  * Bacula floating point time and date routines -- John Walker
22  *
23  * Later double precision integer time/date routines -- Kern Sibbald
24  *
25  */
26
27 /*
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.
33  *
34  *  Epoch is the base of Unix time in seconds (time_t, ...)
35  *     and is 1 Jan 1970 at 0:0 UTC
36  *
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)
40  */
41
42 #include "bacula.h"
43 #include <math.h>
44
45 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
46 char *bstrftime(char *dt, int maxlen, utime_t utime)
47 {
48    time_t time = (time_t)utime;
49    struct tm tm;
50
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);
54    return dt;
55 }
56
57 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
58 char *bstrftimes(char *dt, int maxlen, utime_t utime)
59 {
60    time_t time = (time_t)utime;
61    struct tm tm;
62
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);
66    return dt;
67 }
68
69 /* Formatted time with day name for user display: dd-Mon hh:mm */
70 char *bstrftime_dn(char *dt, int maxlen, utime_t utime)
71 {
72    time_t time = (time_t)utime;
73    struct tm tm;
74
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);
78    return dt;
79 }
80
81 /* Formatted time (no year) for user display: dd-Mon hh:mm */
82 char *bstrftime_ny(char *dt, int maxlen, utime_t utime)
83 {
84    time_t time = (time_t)utime;
85    struct tm tm;
86
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);
90    return dt;
91 }
92
93
94 /* Formatted time for user display: dd-Mon-yy hh:mm  (no century) */
95 char *bstrftime_nc(char *dt, int maxlen, utime_t utime)
96 {
97    time_t time = (time_t)utime;
98    struct tm tm;
99    char *p, *q;
100
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 */
106    p = dt+7;
107    q = dt+9;
108    while (*q) {
109       *p++ = *q++;
110    }
111    *p = 0;
112    return dt;
113 }
114
115
116 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
117 char *bstrutime(char *dt, int maxlen, utime_t utime)
118 {
119    time_t time = (time_t)utime;
120    struct tm tm;
121    (void)localtime_r(&time, &tm);
122    strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
123    return dt;
124 }
125
126 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
127 utime_t str_to_utime(char *str)
128 {
129    struct tm tm;
130    time_t time;
131
132    /* Check for bad argument */
133    if (!str || *str == 0) {
134       return 0;
135    }
136
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) {
139       return 0;
140    }
141    if (tm.tm_mon > 0) {
142       tm.tm_mon--;
143    } else {
144       return 0;
145    }
146    if (tm.tm_year >= 1900) {
147       tm.tm_year -= 1900;
148    } else {
149       return 0;
150    }
151    tm.tm_wday = tm.tm_yday = 0;
152    tm.tm_isdst = -1;
153    time = mktime(&tm);
154    if (time == -1) {
155       time = 0;
156    }
157    return (utime_t)time;
158 }
159
160
161 /*
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.
164  */
165
166 btime_t get_current_btime()
167 {
168    struct timeval tv;
169    if (gettimeofday(&tv, NULL) != 0) {
170       tv.tv_sec = (long)time(NULL);   /* fall back to old method */
171       tv.tv_usec = 0;
172    }
173    return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
174 }
175
176 /* Convert btime to Unix time */
177 time_t btime_to_unix(btime_t bt)
178 {
179    return (time_t)(bt/1000000);
180 }
181
182 /* Convert btime to utime */
183 utime_t btime_to_utime(btime_t bt)
184 {
185    return (utime_t)(bt/1000000);
186 }
187
188 /*
189  * Definition of a leap year from Wikipedia.
190  *  I knew it anyway but better check.
191  */
192 static bool is_leap_year(int year)
193 {
194    if (year % 400 == 0) return true;
195    if (year % 100 == 0) return false;
196    if (year % 4 == 0) return true;
197    return false;
198 }
199
200 /*
201  * Return the last day of the month, base 0
202  *   month=0-11, year is actual year
203  *   ldom is base 0
204  */
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};
208
209    if (is_leap_year(year) && month == 1) return 28;
210    return dom[month] - 1;
211 }
212
213 /*
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
217  */
218 int tm_wom(int mday, int wday)
219 {
220    int fs;                       /* first sunday */
221    fs = (mday%7) - wday;
222    if (fs <= 0) {
223       fs += 7;
224    }
225    if (mday <= fs) {
226 //    Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
227       return 0;
228    }
229    int wom = 1 + (mday - fs - 1) / 7;
230 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
231    return wom;
232 }
233
234 /*
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.
242  */
243 int tm_woy(time_t stime)
244 {
245    int woy, fty, tm_yday;
246    time_t time4;
247    struct tm tm;
248
249    memset(&tm, 0, sizeof(struct tm));
250    (void)localtime_r(&stime, &tm);
251    tm_yday = tm.tm_yday;
252    tm.tm_mon = 0;
253    tm.tm_mday = 4;
254    tm.tm_isdst = 0;                   /* 4 Jan is not DST */
255    time4 = mktime(&tm);
256    (void)localtime_r(&time4, &tm);
257    fty = 1 - tm.tm_wday;
258    if (fty <= 0) {
259       fty += 7;
260    }
261    woy = tm_yday - fty + 4;
262    if (woy < 0) {
263       return 0;
264    }
265    return 1 + woy / 7;
266 }
267
268 /* Deprecated. Do not use. */
269 void get_current_time(struct date_time *dt)
270 {
271    struct tm tm;
272    time_t now;
273
274    now = time(NULL);
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);
278    tm_encode(dt, &tm);
279 #ifdef DEBUG
280    Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
281    tm_decode(dt, &tm);
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);
284 #endif
285 }
286
287
288
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)
292 {
293
294     /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
295
296     int32_t a, b, m;
297     uint32_t y;
298
299     ASSERT(month < 13);
300     ASSERT(day > 0 && day < 32);
301
302     m = month;
303     y = year;
304
305     if (m <= 2) {
306         y--;
307         m += 12;
308     }
309
310     /* Determine whether date is in Julian or Gregorian calendar based on
311        canonical date of calendar reform. */
312
313     if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
314         b = 0;
315     } else {
316         a = ((int) (y / 100));
317         b = 2 - a + (a / 4);
318     }
319
320     return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
321                 day + b - 1524.5);
322 }
323
324 /*  time_encode  --  Encode time from hours, minutes, and seconds
325                      into a fraction of a day.  */
326
327 /* Deprecated. Do not use. */
328 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
329                    float32_t second_fraction)
330 {
331     ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
332     return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
333                      second_fraction;
334 }
335
336 /*  date_time_encode  --  Set day number and fraction from date
337                           and time.  */
338
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)
344 {
345     dt->julian_day_number = date_encode(year, month, day);
346     dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
347 }
348
349 /*  date_decode  --  Decode a Julian day number into civil date.  */
350
351 /* Deprecated. Do not use. */
352 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
353                  uint8_t *day)
354 {
355     fdate_t z, f, a, alpha, b, c, d, e;
356
357     date += 0.5;
358     z = floor(date);
359     f = date - z;
360
361     if (z < 2299161.0) {
362         a = z;
363     } else {
364         alpha = floor((z - 1867216.25) / 36524.25);
365         a = z + 1 + alpha - floor(alpha / 4);
366     }
367
368     b = a + 1524;
369     c = floor((b - 122.1) / 365.25);
370     d = floor(365.25 * c);
371     e = floor((b - d) / 30.6001);
372
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));
376 }
377
378 /*  time_decode  --  Decode a day fraction into civil time.  */
379
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)
383 {
384     uint32_t ij;
385
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));
392     }
393 }
394
395 /*  date_time_decode  --  Decode a Julian day and day fraction
396                           into civil date and time.  */
397
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)
403 {
404     date_decode(dt->julian_day_number, year, month, day);
405     time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
406 }
407
408 /*  tm_encode  --  Encode a civil date and time from a tm structure
409  *                 to a Julian day and day fraction.
410  */
411
412 /* Deprecated. Do not use. */
413 void tm_encode(struct date_time *dt,
414                       struct tm *tm)
415 {
416     uint32_t year;
417     uint8_t month, day, hour, minute, second;
418
419     year = tm->tm_year + 1900;
420     month = tm->tm_mon + 1;
421     day = tm->tm_mday;
422     hour = tm->tm_hour;
423     minute = tm->tm_min;
424     second = tm->tm_sec;
425     dt->julian_day_number = date_encode(year, month, day);
426     dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
427 }
428
429
430 /*  tm_decode  --  Decode a Julian day and day fraction
431                    into civil date and time in tm structure */
432
433 /* Deprecated. Do not use. */
434 void tm_decode(struct date_time *dt,
435                       struct tm *tm)
436 {
437     uint32_t year;
438     uint8_t month, day, hour, minute, second;
439
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;
444     tm->tm_mday = day;
445     tm->tm_hour = hour;
446     tm->tm_min = minute;
447     tm->tm_sec = second;
448 }
449
450
451 /*  date_time_compare  --  Compare two dates and times and return
452                            the relationship as follows:
453
454                                     -1    dt1 < dt2
455                                      0    dt1 = dt2
456                                      1    dt1 > dt2
457 */
458
459 /* Deprecated. Do not use. */
460 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
461 {
462     if (dt1->julian_day_number == dt2->julian_day_number) {
463         if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
464             return 0;
465         }
466         return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
467     }
468     return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;
469 }