]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/btime.c
kes Add dev->close() in dir_ask_sysop_to_mount_volume() in
[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    if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
109                                         &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
110       return 0;
111    }
112    if (tm.tm_mon > 0) {
113       tm.tm_mon--;
114    } else {
115       return 0;
116    }
117    if (tm.tm_year >= 1900) {
118       tm.tm_year -= 1900;
119    } else {
120       return 0;
121    }
122    tm.tm_wday = tm.tm_yday = 0;
123    tm.tm_isdst = -1;
124    ttime = mktime(&tm);
125    if (ttime == -1) {
126       ttime = 0;
127    }
128    return (utime_t)ttime;
129 }
130
131
132 /*
133  * Bacula's time (btime_t) is an unsigned 64 bit integer that contains
134  *   the number of microseconds since Epoch Time (1 Jan 1970) UTC.
135  */
136
137 btime_t get_current_btime()
138 {
139    struct timeval tv;
140    if (gettimeofday(&tv, NULL) != 0) {
141       tv.tv_sec = (long)time(NULL);   /* fall back to old method */
142       tv.tv_usec = 0;
143    }
144    return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec;
145 }
146
147 /* Convert btime to Unix time */
148 time_t btime_to_unix(btime_t bt)
149 {
150    return (time_t)(bt/1000000);
151 }
152
153 /* Convert btime to utime */
154 utime_t btime_to_utime(btime_t bt)
155 {
156    return (utime_t)(bt/1000000);
157 }
158
159 /*
160  * Return the week of the month, base 0 (wom)
161  *   given tm_mday and tm_wday. Value returned
162  *   can be from 0 to 4 => week1, ... week5
163  */
164 int tm_wom(int mday, int wday)
165 {
166    int fs;                       /* first sunday */
167    fs = (mday%7) - wday;
168    if (fs <= 0) {
169       fs += 7;
170    }
171    if (mday <= fs) {
172 //    Dmsg3(100, "mday=%d wom=0 wday=%d <= fs=%d\n", mday, wday, fs);
173       return 0;
174    }
175    int wom = 1 + (mday - fs - 1) / 7;
176 // Dmsg4(100, "mday=%d wom=%d wday=%d fs=%d\n", mday, wom, wday, fs);
177    return wom;
178 }
179
180 /*
181  * Given a Unix date return the week of the year.
182  * The returned value can be 0-53.  Officially
183  * the weeks are numbered from 1 to 53 where week1
184  * is the week in which the first Thursday of the
185  * year occurs (alternatively, the week which contains
186  * the 4th of January).  We return 0, if the week of the
187  * year does not fall in the current year.
188  */
189 int tm_woy(time_t stime)
190 {
191    int woy, fty, tm_yday;
192    time_t time4;
193    struct tm tm;
194    memset(&tm, 0, sizeof(struct tm));
195    (void)localtime_r(&stime, &tm);
196    tm_yday = tm.tm_yday;
197    tm.tm_mon = 0;
198    tm.tm_mday = 4;
199    time4 = mktime(&tm);
200    (void)localtime_r(&time4, &tm);
201    fty = 1 - tm.tm_wday;
202    if (fty <= 0) {
203       fty += 7;
204    }
205    woy = tm_yday - fty + 4;
206    if (woy < 0) {
207       return 0;
208    }
209    return 1 + woy / 7;
210 }
211
212 /* Deprecated. Do not use. */
213 void get_current_time(struct date_time *dt)
214 {
215    struct tm tm;
216    time_t now;
217
218    now = time(NULL);
219    (void)gmtime_r(&now, &tm);
220    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,
221       tm.tm_hour, tm.tm_min, tm.tm_sec);
222    tm_encode(dt, &tm);
223 #ifdef DEBUG
224    Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction);
225    tm_decode(dt, &tm);
226    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,
227       tm.tm_hour, tm.tm_min, tm.tm_sec);
228 #endif
229 }
230
231
232 /*  date_encode  --  Encode civil date as a Julian day number.  */
233
234 /* Deprecated. Do not use. */
235 fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day)
236 {
237
238     /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */
239
240     int32_t a, b, m;
241     uint32_t y;
242
243     ASSERT(month < 13);
244     ASSERT(day > 0 && day < 32);
245
246     m = month;
247     y = year;
248
249     if (m <= 2) {
250         y--;
251         m += 12;
252     }
253
254     /* Determine whether date is in Julian or Gregorian calendar based on
255        canonical date of calendar reform. */
256
257     if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) {
258         b = 0;
259     } else {
260         a = ((int) (y / 100));
261         b = 2 - a + (a / 4);
262     }
263
264     return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) +
265                 day + b - 1524.5);
266 }
267
268 /*  time_encode  --  Encode time from hours, minutes, and seconds
269                      into a fraction of a day.  */
270
271 /* Deprecated. Do not use. */
272 ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second,
273                    float32_t second_fraction)
274 {
275     ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0));
276     return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) +
277                      second_fraction;
278 }
279
280 /*  date_time_encode  --  Set day number and fraction from date
281                           and time.  */
282
283 /* Deprecated. Do not use. */
284 void date_time_encode(struct date_time *dt,
285                       uint32_t year, uint8_t month, uint8_t day,
286                       uint8_t hour, uint8_t minute, uint8_t second,
287                       float32_t second_fraction)
288 {
289     dt->julian_day_number = date_encode(year, month, day);
290     dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction);
291 }
292
293 /*  date_decode  --  Decode a Julian day number into civil date.  */
294
295 /* Deprecated. Do not use. */
296 void date_decode(fdate_t date, uint32_t *year, uint8_t *month,
297                  uint8_t *day)
298 {
299     fdate_t z, f, a, alpha, b, c, d, e;
300
301     date += 0.5;
302     z = floor(date);
303     f = date - z;
304
305     if (z < 2299161.0) {
306         a = z;
307     } else {
308         alpha = floor((z - 1867216.25) / 36524.25);
309         a = z + 1 + alpha - floor(alpha / 4);
310     }
311
312     b = a + 1524;
313     c = floor((b - 122.1) / 365.25);
314     d = floor(365.25 * c);
315     e = floor((b - d) / 30.6001);
316
317     *day = (uint8_t) (b - d - floor(30.6001 * e) + f);
318     *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13));
319     *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715));
320 }
321
322 /*  time_decode  --  Decode a day fraction into civil time.  */
323
324 /* Deprecated. Do not use. */
325 void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute,
326                  uint8_t *second, float32_t *second_fraction)
327 {
328     uint32_t ij;
329
330     ij = (uint32_t) ((time - floor(time)) * 86400.0);
331     *hour = (uint8_t) (ij / 3600L);
332     *minute = (uint8_t) ((ij / 60L) % 60L);
333     *second = (uint8_t) (ij % 60L);
334     if (second_fraction != NULL) {
335         *second_fraction = (float32_t)(time - floor(time));
336     }
337 }
338
339 /*  date_time_decode  --  Decode a Julian day and day fraction
340                           into civil date and time.  */
341
342 /* Deprecated. Do not use. */
343 void date_time_decode(struct date_time *dt,
344                       uint32_t *year, uint8_t *month, uint8_t *day,
345                       uint8_t *hour, uint8_t *minute, uint8_t *second,
346                       float32_t *second_fraction)
347 {
348     date_decode(dt->julian_day_number, year, month, day);
349     time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction);
350 }
351
352 /*  tm_encode  --  Encode a civil date and time from a tm structure
353  *                 to a Julian day and day fraction.
354  */
355
356 /* Deprecated. Do not use. */
357 void tm_encode(struct date_time *dt,
358                       struct tm *tm)
359 {
360     uint32_t year;
361     uint8_t month, day, hour, minute, second;
362
363     year = tm->tm_year + 1900;
364     month = tm->tm_mon + 1;
365     day = tm->tm_mday;
366     hour = tm->tm_hour;
367     minute = tm->tm_min;
368     second = tm->tm_sec;
369     dt->julian_day_number = date_encode(year, month, day);
370     dt->julian_day_fraction = time_encode(hour, minute, second, 0.0);
371 }
372
373
374 /*  tm_decode  --  Decode a Julian day and day fraction
375                    into civil date and time in tm structure */
376
377 /* Deprecated. Do not use. */
378 void tm_decode(struct date_time *dt,
379                       struct tm *tm)
380 {
381     uint32_t year;
382     uint8_t month, day, hour, minute, second;
383
384     date_decode(dt->julian_day_number, &year, &month, &day);
385     time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL);
386     tm->tm_year = year - 1900;
387     tm->tm_mon = month - 1;
388     tm->tm_mday = day;
389     tm->tm_hour = hour;
390     tm->tm_min = minute;
391     tm->tm_sec = second;
392 }
393
394
395 /*  date_time_compare  --  Compare two dates and times and return
396                            the relationship as follows:
397
398                                     -1    dt1 < dt2
399                                      0    dt1 = dt2
400                                      1    dt1 > dt2
401 */
402
403 /* Deprecated. Do not use. */
404 int date_time_compare(struct date_time *dt1, struct date_time *dt2)
405 {
406     if (dt1->julian_day_number == dt2->julian_day_number) {
407         if (dt1->julian_day_fraction == dt2->julian_day_fraction) {
408             return 0;
409         }
410         return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1;
411     }
412     return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1;
413 }