]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/btime.c
kes Correctly detect Ubuntu systems, and add ubuntu platform directory.
[bacula/bacula] / bacula / src / lib / btime.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 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 two of the GNU 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 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 John Walker.
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  *   Version $Id$
34  */
35
36
37 /* Concerning times. There are a number of differnt time standards
38  * in Bacula (fdate_t, ftime_t, time_t (Unix standard), btime_t, and
39  *  utime_t).  fdate_t and ftime_t are deprecated and should no longer
40  *  be used, and in general, Unix time time_t should no longer be used,
41  *  it is being phased out.
42  *
43  *  Epoch is the base of Unix time in seconds (time_t, ...)
44  *     and is 1 Jan 1970 at 0:0 UTC
45  *
46  *  The major two times that should be left are:
47  *     btime_t  (64 bit integer in microseconds base Epoch)
48  *     utime_t  (64 bit integer in seconds base Epoch)
49  */
50
51 #include "bacula.h"
52 #include <math.h>
53
54 /* Formatted time for user display: dd-Mon-yyyy hh:mm */
55 char *bstrftime(char *dt, int maxlen, utime_t tim)
56 {
57    time_t ttime = (time_t)tim;
58    struct tm tm;
59
60    /* ***FIXME**** the format and localtime_r() should be user configurable */
61    (void)localtime_r(&ttime, &tm);
62    strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
63    return dt;
64 }
65
66 /* Formatted time for user display: dd-Mon-yyyy hh:mm:ss */
67 char *bstrftimes(char *dt, int maxlen, utime_t tim)
68 {
69    time_t ttime = (time_t)tim;
70    struct tm tm;
71
72    /* ***FIXME**** the format and localtime_r() should be user configurable */
73    (void)localtime_r(&ttime, &tm);
74    strftime(dt, maxlen, "%d-%b-%Y %H:%M:%S", &tm);
75    return dt;
76 }
77
78
79 /* Formatted time for user display: dd-Mon hh:mm */
80 char *bstrftime_ny(char *dt, int maxlen, utime_t tim)
81 {
82    time_t ttime = (time_t)tim;
83    struct tm tm;
84
85    /* ***FIXME**** the format and localtime_r() should be user configurable */
86    (void)localtime_r(&ttime, &tm);
87    strftime(dt, maxlen, "%d-%b %H:%M", &tm);
88    return dt;
89 }
90
91
92 /* Formatted time for user display: dd-Mon-yy hh:mm  (no century) */
93 char *bstrftime_nc(char *dt, int maxlen, utime_t tim)
94 {
95    time_t ttime = (time_t)tim;
96    struct tm tm;
97    char *p, *q;
98
99    /* ***FIXME**** the format and localtime_r() should be user configurable */
100    (void)localtime_r(&ttime, &tm);
101    /* NOTE! since the compiler complains about %y, I use %y and cut the century */
102    strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm);
103    /* overlay the century */
104    p = dt+7;
105    q = dt+9;
106    while (*q) {
107       *p++ = *q++;
108    }
109    *p = 0;
110    return dt;
111 }
112
113
114 /* Unix time to standard time string yyyy-mm-dd hh:mm:ss */
115 char *bstrutime(char *dt, int maxlen, utime_t tim)
116 {
117    time_t ttime = (time_t)tim;
118    struct tm tm;
119    (void)localtime_r(&ttime, &tm);
120    strftime(dt, maxlen, "%Y-%m-%d %H:%M:%S", &tm);
121    return dt;
122 }
123
124 /* Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */
125 utime_t str_to_utime(char *str)
126 {
127    struct tm tm;
128    time_t ttime;
129
130    /* Check for bad argument */
131    if (!str || *str == 0) {
132       return 0;
133    }
134
135    if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
136                                         &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
137       return 0;
138    }
139    if (tm.tm_mon > 0) {
140       tm.tm_mon--;
141    } else {
142       return 0;
143    }
144    if (tm.tm_year >= 1900) {
145       tm.tm_year -= 1900;
146    } else {
147       return 0;
148    }
149    tm.tm_wday = tm.tm_yday = 0;
150    tm.tm_isdst = -1;
151    ttime = mktime(&tm);
152    if (ttime == -1) {
153       ttime = 0;
154    }
155    return (utime_t)ttime;
156 }
157
158
159 /*
160  * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
161  *   the number of microseconds since Epoch Time (1 Jan 1970) UTC.
162  */
163
164 btime_t get_current_btime()
165 {
166    struct timeval tv;
167    if (gettimeofday(&tv, NULL) != 0) {
168       tv.tv_sec = (long)time(NULL);   /* fall back to old method */
169       tv.tv_usec = 0;
170    }
171    return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
172 }
173
174 /* Convert btime to Unix time */
175 time_t btime_to_unix(btime_t bt)
176 {
177    return (time_t)(bt/1000000);
178 }
179
180 /* Convert btime to utime */
181 utime_t btime_to_utime(btime_t bt)
182 {
183    return (utime_t)(bt/1000000);
184 }
185
186 /*
187  * Return the week of the month, base 0 (wom)
188  *   given tm_mday and tm_wday. Value returned
189  *   can be from 0 to 4 => week1, ... week5
190  */
191 int tm_wom(int mday, int wday)
192 {
193    int fs;                       /* first sunday */
194    fs = (mday%7) - wday;
195    if (fs <= 0) {
196       fs += 7;
197    }
198    if (mday <= fs) {
199 //    Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
200       return 0;
201    }
202    int wom = 1 + (mday - fs - 1) / 7;
203 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
204    return wom;
205 }
206
207 /*
208  * Given a Unix date return the week of the year.
209  * The returned value can be 0-53.  Officially
210  * the weeks are numbered from 1 to 53 where week1
211  * is the week in which the first Thursday of the
212  * year occurs (alternatively, the week which contains
213  * the 4th of January).  We return 0, if the week of the
214  * year does not fall in the current year.
215  */
216 int tm_woy(time_t stime)
217 {
218    int woy, fty, tm_yday;
219    time_t time4;
220    struct tm tm;
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 }