]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/btime.c
58487769b2f617592a8a15217a77e57ebc158fc1
[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 plus additions
11    that are listed 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    time4 = mktime(&tm);
227    (void)localtime_r(&time4, &tm);
228    fty = 1 - tm.tm_wday;
229    if (fty <= 0) {
230       fty += 7;
231    }
232    woy = tm_yday - fty + 4;
233    if (woy < 0) {
234       return 0;
235    }
236    return 1 + woy / 7;
237 }
238
239 /* Deprecated. Do not use. */
240 void get_current_time(struct date_time *dt)
241 {
242    struct tm tm;
243    time_t now;
244
245    now = time(NULL);
246    (void)gmtime_r(&now, &tm);
247    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,
248       tm.tm_hour, tm.tm_min, tm.tm_sec);
249    tm_encode(dt, &tm);
250 #ifdef DEBUG
251    Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
252    tm_decode(dt, &tm);
253    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,
254       tm.tm_hour, tm.tm_min, tm.tm_sec);
255 #endif
256 }
257
258
259 /*  date_encode  --  Encode civil date as a Julian day number.  */
260
261 /* Deprecated. Do not use. */
262 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
263 {
264
265     /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
266
267     int32_t a, b, m;
268     uint32_t y;
269
270     ASSERT(month < 13);
271     ASSERT(day > 0 && day < 32);
272
273     m = month;
274     y = year;
275
276     if (m <= 2) {
277         y--;
278         m += 12;
279     }
280
281     /* Determine whether date is in Julian or Gregorian calendar based on
282        canonical date of calendar reform. */
283
284     if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
285         b = 0;
286     } else {
287         a = ((int) (y / 100));
288         b = 2 - a + (a / 4);
289     }
290
291     return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
292                 day + b - 1524.5);
293 }
294
295 /*  time_encode  --  Encode time from hours, minutes, and seconds
296                      into a fraction of a day.  */
297
298 /* Deprecated. Do not use. */
299 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
300                    float32_t second_fraction)
301 {
302     ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
303     return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
304                      second_fraction;
305 }
306
307 /*  date_time_encode  --  Set day number and fraction from date
308                           and time.  */
309
310 /* Deprecated. Do not use. */
311 void date_time_encode(struct date_time *dt,
312                       uint32_t year, uint8_t month, uint8_t day,
313                       uint8_t hour, uint8_t minute, uint8_t second,
314                       float32_t second_fraction)
315 {
316     dt->julian_day_number = date_encode(year, month, day);
317     dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
318 }
319
320 /*  date_decode  --  Decode a Julian day number into civil date.  */
321
322 /* Deprecated. Do not use. */
323 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
324                  uint8_t *day)
325 {
326     fdate_t z, f, a, alpha, b, c, d, e;
327
328     date += 0.5;
329     z = floor(date);
330     f = date - z;
331
332     if (z < 2299161.0) {
333         a = z;
334     } else {
335         alpha = floor((z - 1867216.25) / 36524.25);
336         a = z + 1 + alpha - floor(alpha / 4);
337     }
338
339     b = a + 1524;
340     c = floor((b - 122.1) / 365.25);
341     d = floor(365.25 * c);
342     e = floor((b - d) / 30.6001);
343
344     *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
345     *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
346     *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
347 }
348
349 /*  time_decode  --  Decode a day fraction into civil time.  */
350
351 /* Deprecated. Do not use. */
352 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
353                  uint8_t *second, float32_t *second_fraction)
354 {
355     uint32_t ij;
356
357     ij = (uint32_t) ((time - floor(time)) * 86400.0);
358     *hour = (uint8_t) (ij / 3600L);
359     *minute = (uint8_t) ((ij / 60L) % 60L);
360     *second = (uint8_t) (ij % 60L);
361     if (second_fraction != NULL) {
362         *second_fraction = (float32_t)(time - floor(time));
363     }
364 }
365
366 /*  date_time_decode  --  Decode a Julian day and day fraction
367                           into civil date and time.  */
368
369 /* Deprecated. Do not use. */
370 void date_time_decode(struct date_time *dt,
371                       uint32_t *year, uint8_t *month, uint8_t *day,
372                       uint8_t *hour, uint8_t *minute, uint8_t *second,
373                       float32_t *second_fraction)
374 {
375     date_decode(dt->julian_day_number, year, month, day);
376     time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
377 }
378
379 /*  tm_encode  --  Encode a civil date and time from a tm structure
380  *                 to a Julian day and day fraction.
381  */
382
383 /* Deprecated. Do not use. */
384 void tm_encode(struct date_time *dt,
385                       struct tm *tm)
386 {
387     uint32_t year;
388     uint8_t month, day, hour, minute, second;
389
390     year = tm->tm_year + 1900;
391     month = tm->tm_mon + 1;
392     day = tm->tm_mday;
393     hour = tm->tm_hour;
394     minute = tm->tm_min;
395     second = tm->tm_sec;
396     dt->julian_day_number = date_encode(year, month, day);
397     dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
398 }
399
400
401 /*  tm_decode  --  Decode a Julian day and day fraction
402                    into civil date and time in tm structure */
403
404 /* Deprecated. Do not use. */
405 void tm_decode(struct date_time *dt,
406                       struct tm *tm)
407 {
408     uint32_t year;
409     uint8_t month, day, hour, minute, second;
410
411     date_decode(dt->julian_day_number, &year, &month, &day);
412     time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
413     tm->tm_year = year - 1900;
414     tm->tm_mon = month - 1;
415     tm->tm_mday = day;
416     tm->tm_hour = hour;
417     tm->tm_min = minute;
418     tm->tm_sec = second;
419 }
420
421
422 /*  date_time_compare  --  Compare two dates and times and return
423                            the relationship as follows:
424
425                                     -1    dt1 < dt2
426                                      0    dt1 = dt2
427                                      1    dt1 > dt2
428 */
429
430 /* Deprecated. Do not use. */
431 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
432 {
433     if (dt1->julian_day_number == dt2->julian_day_number) {
434         if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
435             return 0;
436         }
437         return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
438     }
439     return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;
440 }