]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/btime.c
Update version + date
[bacula/bacula] / bacula / src / lib / btime.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Bacula floating point time and date routines -- John Walker
30  *
31  * Later double precision integer time/date routines -- Kern Sibbald
32  *
33  */
34
35
36 /* Concerning times. There are a number of differnt time standards
37  * in Bacula (fdate_t, ftime_t, time_t (Unix standard), btime_t, and
38  *  utime_t).  fdate_t and ftime_t are deprecated and should no longer
39  *  be used, and in general, Unix time time_t should no longer be used,
40  *  it is being phased out.
41  *
42  *  Epoch is the base of Unix time in seconds (time_t, ...)
43  *     and is 1 Jan 1970 at 0:0 UTC
44  *
45  *  The major two times that should be left are:
46  *     btime_t  (64 bit integer in microseconds base Epoch)
47  *     utime_t  (64 bit integer in seconds base Epoch)
48  */
49
50 #include "bacula.h"
51 #include <math.h>
52
53 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
54 char *bstrftime(char *dt, int maxlen, utime_t utime)
55 {
56    time_t time = (time_t)utime;
57    struct tm tm;
58
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", &tm);
62    return dt;
63 }
64
65 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
66 char *bstrftimes(char *dt, int maxlen, utime_t utime)
67 {
68    time_t time = (time_t)utime;
69    struct tm tm;
70
71    /* ***FIXME**** the format and localtime_r() should be user configurable */
72    (void)localtime_r(&time, &tm);
73    strftime(dt, maxlen, "%d-%b-%Y %H:%M:%S", &tm);
74    return dt;
75 }
76
77
78 /* Formatted time for user display: dd-Mon hh:mm */
79 char *bstrftime_ny(char *dt, int maxlen, utime_t utime)
80 {
81    time_t time = (time_t)utime;
82    struct tm tm;
83
84    /* ***FIXME**** the format and localtime_r() should be user configurable */
85    (void)localtime_r(&time, &tm);
86    strftime(dt, maxlen, "%d-%b %H:%M", &tm);
87    return dt;
88 }
89
90
91 /* Formatted time for user display: dd-Mon-yy hh:mm  (no century) */
92 char *bstrftime_nc(char *dt, int maxlen, utime_t utime)
93 {
94    time_t time = (time_t)utime;
95    struct tm tm;
96    char *p, *q;
97
98    /* ***FIXME**** the format and localtime_r() should be user configurable */
99    (void)localtime_r(&time, &tm);
100    /* NOTE! since the compiler complains about %y, I use %y and cut the century */
101    strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
102    /* overlay the century */
103    p = dt+7;
104    q = dt+9;
105    while (*q) {
106       *p++ = *q++;
107    }
108    *p = 0;
109    return dt;
110 }
111
112
113 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
114 char *bstrutime(char *dt, int maxlen, utime_t utime)
115 {
116    time_t time = (time_t)utime;
117    struct tm tm;
118    (void)localtime_r(&time, &tm);
119    strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
120    return dt;
121 }
122
123 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
124 utime_t str_to_utime(char *str)
125 {
126    struct tm tm;
127    time_t time;
128
129    /* Check for bad argument */
130    if (!str || *str == 0) {
131       return 0;
132    }
133
134    if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
135                                         &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
136       return 0;
137    }
138    if (tm.tm_mon > 0) {
139       tm.tm_mon--;
140    } else {
141       return 0;
142    }
143    if (tm.tm_year >= 1900) {
144       tm.tm_year -= 1900;
145    } else {
146       return 0;
147    }
148    tm.tm_wday = tm.tm_yday = 0;
149    tm.tm_isdst = -1;
150    time = mktime(&tm);
151    if (time == -1) {
152       time = 0;
153    }
154    return (utime_t)time;
155 }
156
157
158 /*
159  * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
160  *   the number of microseconds since Epoch Time (1 Jan 1970) UTC.
161  */
162
163 btime_t get_current_btime()
164 {
165    struct timeval tv;
166    if (gettimeofday(&tv, NULL) != 0) {
167       tv.tv_sec = (long)time(NULL);   /* fall back to old method */
168       tv.tv_usec = 0;
169    }
170    return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
171 }
172
173 /* Convert btime to Unix time */
174 time_t btime_to_unix(btime_t bt)
175 {
176    return (time_t)(bt/1000000);
177 }
178
179 /* Convert btime to utime */
180 utime_t btime_to_utime(btime_t bt)
181 {
182    return (utime_t)(bt/1000000);
183 }
184
185 /*
186  * Return the week of the month, base 0 (wom)
187  *   given tm_mday and tm_wday. Value returned
188  *   can be from 0 to 4 => week1, ... week5
189  */
190 int tm_wom(int mday, int wday)
191 {
192    int fs;                       /* first sunday */
193    fs = (mday%7) - wday;
194    if (fs <= 0) {
195       fs += 7;
196    }
197    if (mday <= fs) {
198 //    Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
199       return 0;
200    }
201    int wom = 1 + (mday - fs - 1) / 7;
202 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
203    return wom;
204 }
205
206 /*
207  * Given a Unix date return the week of the year.
208  * The returned value can be 0-53.  Officially
209  * the weeks are numbered from 1 to 53 where week1
210  * is the week in which the first Thursday of the
211  * year occurs (alternatively, the week which contains
212  * the 4th of January).  We return 0, if the week of the
213  * year does not fall in the current year.
214  */
215 int tm_woy(time_t stime)
216 {
217    int woy, fty, tm_yday;
218    time_t time4;
219    struct tm tm;
220
221    memset(&tm, 0, sizeof(struct tm));
222    (void)localtime_r(&stime, &tm);
223    tm_yday = tm.tm_yday;
224    tm.tm_mon = 0;
225    tm.tm_mday = 4;
226    tm.tm_isdst = 0;                   /* 4 Jan is not DST */ 
227    time4 = mktime(&tm);
228    (void)localtime_r(&time4, &tm);
229    fty = 1 - tm.tm_wday;
230    if (fty <= 0) {
231       fty += 7;
232    }
233    woy = tm_yday - fty + 4;
234    if (woy < 0) {
235       return 0;
236    }
237    return 1 + woy / 7;
238 }
239
240 /* Deprecated. Do not use. */
241 void get_current_time(struct date_time *dt)
242 {
243    struct tm tm;
244    time_t now;
245
246    now = time(NULL);
247    (void)gmtime_r(&now, &tm);
248    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,
249       tm.tm_hour, tm.tm_min, tm.tm_sec);
250    tm_encode(dt, &tm);
251 #ifdef DEBUG
252    Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
253    tm_decode(dt, &tm);
254    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,
255       tm.tm_hour, tm.tm_min, tm.tm_sec);
256 #endif
257 }
258
259
260 /*  date_encode  --  Encode civil date as a Julian day number.  */
261
262 /* Deprecated. Do not use. */
263 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
264 {
265
266     /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
267
268     int32_t a, b, m;
269     uint32_t y;
270
271     ASSERT(month < 13);
272     ASSERT(day > 0 && day < 32);
273
274     m = month;
275     y = year;
276
277     if (m <= 2) {
278         y--;
279         m += 12;
280     }
281
282     /* Determine whether date is in Julian or Gregorian calendar based on
283        canonical date of calendar reform. */
284
285     if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
286         b = 0;
287     } else {
288         a = ((int) (y / 100));
289         b = 2 - a + (a / 4);
290     }
291
292     return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
293                 day + b - 1524.5);
294 }
295
296 /*  time_encode  --  Encode time from hours, minutes, and seconds
297                      into a fraction of a day.  */
298
299 /* Deprecated. Do not use. */
300 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
301                    float32_t second_fraction)
302 {
303     ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
304     return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
305                      second_fraction;
306 }
307
308 /*  date_time_encode  --  Set day number and fraction from date
309                           and time.  */
310
311 /* Deprecated. Do not use. */
312 void date_time_encode(struct date_time *dt,
313                       uint32_t year, uint8_t month, uint8_t day,
314                       uint8_t hour, uint8_t minute, uint8_t second,
315                       float32_t second_fraction)
316 {
317     dt->julian_day_number = date_encode(year, month, day);
318     dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
319 }
320
321 /*  date_decode  --  Decode a Julian day number into civil date.  */
322
323 /* Deprecated. Do not use. */
324 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
325                  uint8_t *day)
326 {
327     fdate_t z, f, a, alpha, b, c, d, e;
328
329     date += 0.5;
330     z = floor(date);
331     f = date - z;
332
333     if (z < 2299161.0) {
334         a = z;
335     } else {
336         alpha = floor((z - 1867216.25) / 36524.25);
337         a = z + 1 + alpha - floor(alpha / 4);
338     }
339
340     b = a + 1524;
341     c = floor((b - 122.1) / 365.25);
342     d = floor(365.25 * c);
343     e = floor((b - d) / 30.6001);
344
345     *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
346     *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
347     *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
348 }
349
350 /*  time_decode  --  Decode a day fraction into civil time.  */
351
352 /* Deprecated. Do not use. */
353 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
354                  uint8_t *second, float32_t *second_fraction)
355 {
356     uint32_t ij;
357
358     ij = (uint32_t) ((time - floor(time)) * 86400.0);
359     *hour = (uint8_t) (ij / 3600L);
360     *minute = (uint8_t) ((ij / 60L) % 60L);
361     *second = (uint8_t) (ij % 60L);
362     if (second_fraction != NULL) {
363         *second_fraction = (float32_t)(time - floor(time));
364     }
365 }
366
367 /*  date_time_decode  --  Decode a Julian day and day fraction
368                           into civil date and time.  */
369
370 /* Deprecated. Do not use. */
371 void date_time_decode(struct date_time *dt,
372                       uint32_t *year, uint8_t *month, uint8_t *day,
373                       uint8_t *hour, uint8_t *minute, uint8_t *second,
374                       float32_t *second_fraction)
375 {
376     date_decode(dt->julian_day_number, year, month, day);
377     time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
378 }
379
380 /*  tm_encode  --  Encode a civil date and time from a tm structure
381  *                 to a Julian day and day fraction.
382  */
383
384 /* Deprecated. Do not use. */
385 void tm_encode(struct date_time *dt,
386                       struct tm *tm)
387 {
388     uint32_t year;
389     uint8_t month, day, hour, minute, second;
390
391     year = tm->tm_year + 1900;
392     month = tm->tm_mon + 1;
393     day = tm->tm_mday;
394     hour = tm->tm_hour;
395     minute = tm->tm_min;
396     second = tm->tm_sec;
397     dt->julian_day_number = date_encode(year, month, day);
398     dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
399 }
400
401
402 /*  tm_decode  --  Decode a Julian day and day fraction
403                    into civil date and time in tm structure */
404
405 /* Deprecated. Do not use. */
406 void tm_decode(struct date_time *dt,
407                       struct tm *tm)
408 {
409     uint32_t year;
410     uint8_t month, day, hour, minute, second;
411
412     date_decode(dt->julian_day_number, &year, &month, &day);
413     time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
414     tm->tm_year = year - 1900;
415     tm->tm_mon = month - 1;
416     tm->tm_mday = day;
417     tm->tm_hour = hour;
418     tm->tm_min = minute;
419     tm->tm_sec = second;
420 }
421
422
423 /*  date_time_compare  --  Compare two dates and times and return
424                            the relationship as follows:
425
426                                     -1    dt1 < dt2
427                                      0    dt1 = dt2
428                                      1    dt1 > dt2
429 */
430
431 /* Deprecated. Do not use. */
432 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
433 {
434     if (dt1->julian_day_number == dt2->julian_day_number) {
435         if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
436             return 0;
437         }
438         return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
439     }
440     return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;
441 }