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