~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to zip/zip/mktime.c

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* free mktime function
2
 
   Copyright 1988, 1989 by David MacKenzie <djm@ai.mit.edu>
3
 
   and Michael Haertel <mike@ai.mit.edu>
4
 
   Unlimited distribution permitted provided this copyright notice is
5
 
   retained and any functional modifications are prominently identified.  */
6
 
 
7
 
/* Revised 1997 by Christian Spieler:
8
 
   The code was changed to get more conformance with ANSI's (resp. modern
9
 
   UNIX releases) definition for mktime():
10
 
   - Added adjustment for out-of-range values in the fields of struct tm.
11
 
   - Added iterations to get the correct UTC result for input values at
12
 
     the gaps when daylight saving time is switched on or off.
13
 
   - Allow forcing of DST "on" or DST "off" by setting `tm_isdst' field in
14
 
     the tm struct to positive number resp. zero. The `tm_isdst' field must
15
 
     be negative on entrance of mktime() to enable automatic determination
16
 
     if DST is in effect for the requested local time.
17
 
   - Added optional check for overflowing the time_t range.  */
18
 
 
19
 
/* Note: This version of mktime is ignorant of the tzfile.
20
 
   When the tm structure passed to mktime represents a local time that
21
 
   is valid both as DST time and as standard time (= time value in the
22
 
   gap when switching from DST back to standard time), the behaviour
23
 
   for `tm_isdst < 0' depends on the current timezone: TZ east of GMT
24
 
   assumes winter time, TZ west of GMT assumes summer time.
25
 
   Although mktime() (resp. mkgmtime()) tries to adjust for invalid values
26
 
   of struct tm members, this may fail for input values that are far away
27
 
   from the valid ranges. The adjustment process does not check for overflows
28
 
   or wrap arounds in the struct tm components.  */
29
 
 
30
 
#ifndef OF
31
 
#  ifdef __STDC__
32
 
#    define OF(a) a
33
 
#  else
34
 
#    define OF(a) ()
35
 
#  endif
36
 
#endif
37
 
 
38
 
#ifndef ZCONST
39
 
#  define ZCONST const
40
 
#endif
41
 
 
42
 
#include <time.h>
43
 
 
44
 
time_t mkgmtime OF((struct tm *));
45
 
time_t mktime OF((struct tm *));
46
 
 
47
 
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
48
 
   of the local time and date in the exploded time structure `tm',
49
 
   adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'.
50
 
   If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of
51
 
   tm_isdst is determined and returned. Otherwise, mktime() assumes this
52
 
   field as valid; its information is used when converting local time
53
 
   to UTC.
54
 
   Return -1 if time in `tm' cannot be represented as time_t value. */
55
 
 
56
 
time_t
57
 
mktime(tm)
58
 
     struct tm *tm;
59
 
{
60
 
  struct tm *ltm;               /* Local time. */
61
 
  time_t loctime;               /* The time_t value of local time. */
62
 
  time_t then;                  /* The time to return. */
63
 
  long tzoffset_adj;            /* timezone-adjustment `remainder' */
64
 
  int bailout_cnt;              /* counter of tries for tz correction */
65
 
  int save_isdst;               /* Copy of the tm->isdst input value */
66
 
 
67
 
  save_isdst = tm->tm_isdst;
68
 
  loctime = mkgmtime(tm);
69
 
  if (loctime == -1) {
70
 
    tm->tm_isdst = save_isdst;
71
 
    return (time_t)-1;
72
 
  }
73
 
 
74
 
  /* Correct for the timezone and any daylight savings time.
75
 
     The correction is verified and repeated when not correct, to
76
 
     take into account the rare case that a change to or from daylight
77
 
     savings time occurs between when it is the time in `tm' locally
78
 
     and when it is that time in Greenwich. After the second correction,
79
 
     the "timezone & daylight" offset should be correct in all cases. To
80
 
     be sure, we allow a third try, but then the loop is stopped. */
81
 
  bailout_cnt = 3;
82
 
  then = loctime;
83
 
  do {
84
 
    ltm = localtime(&then);
85
 
    if (ltm == (struct tm *)NULL ||
86
 
        (tzoffset_adj = loctime - mkgmtime(ltm)) == 0L)
87
 
      break;
88
 
    then += tzoffset_adj;
89
 
  } while (--bailout_cnt > 0);
90
 
 
91
 
  if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) {
92
 
    /* Signal failure if timezone adjustment did not converge. */
93
 
    tm->tm_isdst = save_isdst;
94
 
    return (time_t)-1;
95
 
  }
96
 
 
97
 
  if (save_isdst >= 0) {
98
 
    if (ltm->tm_isdst  && !save_isdst)
99
 
    {
100
 
      if (then + 3600 < then)
101
 
        then = (time_t)-1;
102
 
      else
103
 
        then += 3600;
104
 
    }
105
 
    else if (!ltm->tm_isdst && save_isdst)
106
 
    {
107
 
      if (then - 3600 > then)
108
 
        then = (time_t)-1;
109
 
      else
110
 
        then -= 3600;
111
 
    }
112
 
    ltm->tm_isdst = save_isdst;
113
 
  }
114
 
 
115
 
  if (tm != ltm)  /* `tm' may already point to localtime's internal storage */
116
 
    *tm = *ltm;
117
 
 
118
 
  return then;
119
 
}
120
 
 
121
 
 
122
 
#ifndef NO_TIME_T_MAX
123
 
   /* Provide default values for the upper limit of the time_t range.
124
 
      These are the result of the decomposition into a `struct tm' for
125
 
      the time value 0xFFFFFFFEL ( = (time_t)-2 ).
126
 
      Note: `(time_t)-1' is reserved for "invalid time"!  */
127
 
#  ifndef TM_YEAR_MAX
128
 
#    define TM_YEAR_MAX         2106
129
 
#  endif
130
 
#  ifndef TM_MON_MAX
131
 
#    define TM_MON_MAX          1       /* February */
132
 
#  endif
133
 
#  ifndef TM_MDAY_MAX
134
 
#    define TM_MDAY_MAX         7
135
 
#  endif
136
 
#  ifndef TM_HOUR_MAX
137
 
#    define TM_HOUR_MAX         6
138
 
#  endif
139
 
#  ifndef TM_MIN_MAX
140
 
#    define TM_MIN_MAX          28
141
 
#  endif
142
 
#  ifndef TM_SEC_MAX
143
 
#    define TM_SEC_MAX          14
144
 
#  endif
145
 
#endif /* NO_TIME_T_MAX */
146
 
 
147
 
/* Adjusts out-of-range values for `tm' field `tm_member'. */
148
 
#define ADJUST_TM(tm_member, tm_carry, modulus) \
149
 
  if ((tm_member) < 0) { \
150
 
    tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
151
 
    tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
152
 
  } else if ((tm_member) >= (modulus)) { \
153
 
    tm_carry += (tm_member) / (modulus); \
154
 
    tm_member = (tm_member) % (modulus); \
155
 
  }
156
 
 
157
 
/* Nonzero if `y' is a leap year, else zero. */
158
 
#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
159
 
 
160
 
/* Number of leap years from 1970 to `y' (not including `y' itself). */
161
 
#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
162
 
 
163
 
/* Additional leapday in February of leap years. */
164
 
#define leapday(m, y) ((m) == 1 && leap (y))
165
 
 
166
 
/* Length of month `m' (0 .. 11) */
167
 
#define monthlen(m, y) (ydays[(m)+1] - ydays[m] + leapday (m, y))
168
 
 
169
 
/* Accumulated number of days from 01-Jan up to start of current month. */
170
 
static ZCONST short ydays[] =
171
 
{
172
 
  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
173
 
};
174
 
 
175
 
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
176
 
   of the Greenwich Mean time and date in the exploded time structure `tm'.
177
 
   This function does always put back normalized values into the `tm' struct,
178
 
   parameter, including the calculated numbers for `tm->tm_yday',
179
 
   `tm->tm_wday', and `tm->tm_isdst'.
180
 
   Returns -1 if the time in the `tm' parameter cannot be represented
181
 
   as valid `time_t' number. */
182
 
 
183
 
time_t
184
 
mkgmtime(tm)
185
 
     struct tm *tm;
186
 
{
187
 
  int years, months, days, hours, minutes, seconds;
188
 
 
189
 
  years = tm->tm_year + 1900;   /* year - 1900 -> year */
190
 
  months = tm->tm_mon;          /* 0..11 */
191
 
  days = tm->tm_mday - 1;       /* 1..31 -> 0..30 */
192
 
  hours = tm->tm_hour;          /* 0..23 */
193
 
  minutes = tm->tm_min;         /* 0..59 */
194
 
  seconds = tm->tm_sec;         /* 0..61 in ANSI C. */
195
 
 
196
 
  ADJUST_TM(seconds, minutes, 60)
197
 
  ADJUST_TM(minutes, hours, 60)
198
 
  ADJUST_TM(hours, days, 24)
199
 
  ADJUST_TM(months, years, 12)
200
 
  if (days < 0)
201
 
    do {
202
 
      if (--months < 0) {
203
 
        --years;
204
 
        months = 11;
205
 
      }
206
 
      days += monthlen(months, years);
207
 
    } while (days < 0);
208
 
  else
209
 
    while (days >= monthlen(months, years)) {
210
 
      days -= monthlen(months, years);
211
 
      if (++months >= 12) {
212
 
        ++years;
213
 
        months = 0;
214
 
      }
215
 
    }
216
 
 
217
 
  /* Restore adjusted values in tm structure */
218
 
  tm->tm_year = years - 1900;
219
 
  tm->tm_mon = months;
220
 
  tm->tm_mday = days + 1;
221
 
  tm->tm_hour = hours;
222
 
  tm->tm_min = minutes;
223
 
  tm->tm_sec = seconds;
224
 
 
225
 
  /* Set `days' to the number of days into the year. */
226
 
  days += ydays[months] + (months > 1 && leap (years));
227
 
  tm->tm_yday = days;
228
 
 
229
 
  /* Now calculate `days' to the number of days since Jan 1, 1970. */
230
 
  days = (unsigned)days + 365 * (unsigned)(years - 1970) +
231
 
         (unsigned)(nleap (years));
232
 
  tm->tm_wday = ((unsigned)days + 4) % 7; /* Jan 1, 1970 was Thursday. */
233
 
  tm->tm_isdst = 0;
234
 
 
235
 
  if (years < 1970)
236
 
    return (time_t)-1;
237
 
 
238
 
#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
239
 
#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
240
 
  if (years > TM_YEAR_MAX ||
241
 
      (years == TM_YEAR_MAX &&
242
 
       (tm->tm_yday > ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
243
 
                      (TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) ||
244
 
        (tm->tm_yday == ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
245
 
                        (TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) &&
246
 
         (hours > TM_HOUR_MAX ||
247
 
          (hours == TM_HOUR_MAX &&
248
 
           (minutes > TM_MIN_MAX ||
249
 
            (minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
250
 
    return (time_t)-1;
251
 
#endif
252
 
#endif
253
 
 
254
 
  return (time_t)(86400L * (unsigned long)(unsigned)days +
255
 
                  3600L * (unsigned long)hours +
256
 
                  (unsigned long)(60 * minutes + seconds));
257
 
}
258
 
 
259
 
const char *BOINC_RCSID_945276575a = "$Id: mktime.c 4979 2005-01-02 18:29:53Z ballen $";