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