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