Subversion Repositories Kolibri OS

Rev

Rev 1906 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1906 Rev 3065
1
/*
1
/*
2
 * mktm_r.c
2
 * mktm_r.c
3
 * Original Author:	Adapted from tzcode maintained by Arthur David Olson.
3
 * Original Author:	Adapted from tzcode maintained by Arthur David Olson.
4
 * Modifications:       Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
4
 * Modifications:       Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
5
 *                      Fixed bug in mday computations - 08/12/04, Alex Mogilnikov 
5
 *                      Fixed bug in mday computations - 08/12/04, Alex Mogilnikov 
6
 *                      Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov 
6
 *                      Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov 
7
 *
7
 *
8
 * Converts the calendar time pointed to by tim_p into a broken-down time
8
 * Converts the calendar time pointed to by tim_p into a broken-down time
9
 * expressed as local time. Returns a pointer to a structure containing the
9
 * expressed as local time. Returns a pointer to a structure containing the
10
 * broken-down time.
10
 * broken-down time.
11
 */
11
 */
12
 
12
 
13
#include 
13
#include 
14
#include 
14
#include 
15
#include "local.h"
15
#include "local.h"
16
 
16
 
17
static _CONST int mon_lengths[2][MONSPERYEAR] = {
17
static _CONST int mon_lengths[2][MONSPERYEAR] = {
18
  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
18
  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
19
  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
19
  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
20
} ;
20
} ;
21
 
21
 
22
static _CONST int year_lengths[2] = {
22
static _CONST int year_lengths[2] = {
23
  365,
23
  365,
24
  366
24
  366
25
} ;
25
} ;
26
 
26
 
27
struct tm *
27
struct tm *
28
_DEFUN (_mktm_r, (tim_p, res, is_gmtime),
28
_DEFUN (_mktm_r, (tim_p, res, is_gmtime),
29
	_CONST time_t * tim_p _AND
29
	_CONST time_t * tim_p _AND
30
	struct tm *res _AND
30
	struct tm *res _AND
31
	int is_gmtime)
31
	int is_gmtime)
32
{
32
{
33
  long days, rem;
33
  long days, rem;
34
  time_t lcltime;
34
  time_t lcltime;
35
  int y;
35
  int y;
36
  int yleap;
36
  int yleap;
37
  _CONST int *ip;
37
  _CONST int *ip;
38
   __tzinfo_type *tz = __gettzinfo ();
38
   __tzinfo_type *tz = __gettzinfo ();
39
 
39
 
40
  /* base decision about std/dst time on current time */
40
  /* base decision about std/dst time on current time */
41
  lcltime = *tim_p;
41
  lcltime = *tim_p;
42
   
42
   
43
  days = ((long)lcltime) / SECSPERDAY;
43
  days = ((long)lcltime) / SECSPERDAY;
44
  rem = ((long)lcltime) % SECSPERDAY;
44
  rem = ((long)lcltime) % SECSPERDAY;
45
  while (rem < 0) 
45
  while (rem < 0) 
46
    {
46
    {
47
      rem += SECSPERDAY;
47
      rem += SECSPERDAY;
48
      --days;
48
      --days;
49
    }
49
    }
50
  while (rem >= SECSPERDAY)
50
  while (rem >= SECSPERDAY)
51
    {
51
    {
52
      rem -= SECSPERDAY;
52
      rem -= SECSPERDAY;
53
      ++days;
53
      ++days;
54
    }
54
    }
55
 
55
 
56
  /* compute hour, min, and sec */  
56
  /* compute hour, min, and sec */  
57
  res->tm_hour = (int) (rem / SECSPERHOUR);
57
  res->tm_hour = (int) (rem / SECSPERHOUR);
58
  rem %= SECSPERHOUR;
58
  rem %= SECSPERHOUR;
59
  res->tm_min = (int) (rem / SECSPERMIN);
59
  res->tm_min = (int) (rem / SECSPERMIN);
60
  res->tm_sec = (int) (rem % SECSPERMIN);
60
  res->tm_sec = (int) (rem % SECSPERMIN);
61
 
61
 
62
  /* compute day of week */
62
  /* compute day of week */
63
  if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
63
  if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
64
    res->tm_wday += DAYSPERWEEK;
64
    res->tm_wday += DAYSPERWEEK;
65
 
65
 
66
  /* compute year & day of year */
66
  /* compute year & day of year */
67
  y = EPOCH_YEAR;
67
  y = EPOCH_YEAR;
68
  if (days >= 0)
68
  if (days >= 0)
69
    {
69
    {
70
      for (;;)
70
      for (;;)
71
	{
71
	{
72
	  yleap = isleap(y);
72
	  yleap = isleap(y);
73
	  if (days < year_lengths[yleap])
73
	  if (days < year_lengths[yleap])
74
	    break;
74
	    break;
75
	  y++;
75
	  y++;
76
	  days -= year_lengths[yleap];
76
	  days -= year_lengths[yleap];
77
	}
77
	}
78
    }
78
    }
79
  else
79
  else
80
    {
80
    {
81
      do
81
      do
82
	{
82
	{
83
	  --y;
83
	  --y;
84
	  yleap = isleap(y);
84
	  yleap = isleap(y);
85
	  days += year_lengths[yleap];
85
	  days += year_lengths[yleap];
86
	} while (days < 0);
86
	} while (days < 0);
87
    }
87
    }
88
 
88
 
89
  res->tm_year = y - YEAR_BASE;
89
  res->tm_year = y - YEAR_BASE;
90
  res->tm_yday = days;
90
  res->tm_yday = days;
91
  ip = mon_lengths[yleap];
91
  ip = mon_lengths[yleap];
92
  for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
92
  for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
93
    days -= ip[res->tm_mon];
93
    days -= ip[res->tm_mon];
94
  res->tm_mday = days + 1;
94
  res->tm_mday = days + 1;
95
 
95
 
96
  if (!is_gmtime)
96
  if (!is_gmtime)
97
    {
97
    {
98
      long offset;
98
      long offset;
99
      int hours, mins, secs;
99
      int hours, mins, secs;
100
 
100
 
101
      TZ_LOCK;
101
      TZ_LOCK;
102
      if (_daylight)
102
      if (_daylight)
103
	{
103
	{
104
	  if (y == tz->__tzyear || __tzcalc_limits (y))
104
	  if (y == tz->__tzyear || __tzcalc_limits (y))
105
	    res->tm_isdst = (tz->__tznorth 
105
	    res->tm_isdst = (tz->__tznorth 
106
			     ? (*tim_p >= tz->__tzrule[0].change 
106
			     ? (*tim_p >= tz->__tzrule[0].change 
107
				&& *tim_p < tz->__tzrule[1].change)
107
				&& *tim_p < tz->__tzrule[1].change)
108
			     : (*tim_p >= tz->__tzrule[0].change 
108
			     : (*tim_p >= tz->__tzrule[0].change 
109
				|| *tim_p < tz->__tzrule[1].change));
109
				|| *tim_p < tz->__tzrule[1].change));
110
	  else
110
	  else
111
	    res->tm_isdst = -1;
111
	    res->tm_isdst = -1;
112
	}
112
	}
113
      else
113
      else
114
	res->tm_isdst = 0;
114
	res->tm_isdst = 0;
115
 
115
 
116
      offset = (res->tm_isdst == 1 
116
      offset = (res->tm_isdst == 1 
117
		  ? tz->__tzrule[1].offset 
117
		  ? tz->__tzrule[1].offset 
118
		  : tz->__tzrule[0].offset);
118
		  : tz->__tzrule[0].offset);
119
 
119
 
120
      hours = (int) (offset / SECSPERHOUR);
120
      hours = (int) (offset / SECSPERHOUR);
121
      offset = offset % SECSPERHOUR;
121
      offset = offset % SECSPERHOUR;
122
      
122
      
123
      mins = (int) (offset / SECSPERMIN);
123
      mins = (int) (offset / SECSPERMIN);
124
      secs = (int) (offset % SECSPERMIN);
124
      secs = (int) (offset % SECSPERMIN);
125
 
125
 
126
      res->tm_sec -= secs;
126
      res->tm_sec -= secs;
127
      res->tm_min -= mins;
127
      res->tm_min -= mins;
128
      res->tm_hour -= hours;
128
      res->tm_hour -= hours;
129
 
129
 
130
      if (res->tm_sec >= SECSPERMIN)
130
      if (res->tm_sec >= SECSPERMIN)
131
	{
131
	{
132
	  res->tm_min += 1;
132
	  res->tm_min += 1;
133
	  res->tm_sec -= SECSPERMIN;
133
	  res->tm_sec -= SECSPERMIN;
134
	}
134
	}
135
      else if (res->tm_sec < 0)
135
      else if (res->tm_sec < 0)
136
	{
136
	{
137
	  res->tm_min -= 1;
137
	  res->tm_min -= 1;
138
	  res->tm_sec += SECSPERMIN;
138
	  res->tm_sec += SECSPERMIN;
139
	}
139
	}
140
      if (res->tm_min >= MINSPERHOUR)
140
      if (res->tm_min >= MINSPERHOUR)
141
	{
141
	{
142
	  res->tm_hour += 1;
142
	  res->tm_hour += 1;
143
	  res->tm_min -= MINSPERHOUR;
143
	  res->tm_min -= MINSPERHOUR;
144
	}
144
	}
145
      else if (res->tm_min < 0)
145
      else if (res->tm_min < 0)
146
	{
146
	{
147
	  res->tm_hour -= 1;
147
	  res->tm_hour -= 1;
148
	  res->tm_min += MINSPERHOUR;
148
	  res->tm_min += MINSPERHOUR;
149
	}
149
	}
150
      if (res->tm_hour >= HOURSPERDAY)
150
      if (res->tm_hour >= HOURSPERDAY)
151
	{
151
	{
152
	  ++res->tm_yday;
152
	  ++res->tm_yday;
153
	  ++res->tm_wday;
153
	  ++res->tm_wday;
154
	  if (res->tm_wday > 6)
154
	  if (res->tm_wday > 6)
155
	    res->tm_wday = 0;
155
	    res->tm_wday = 0;
156
	  ++res->tm_mday;
156
	  ++res->tm_mday;
157
	  res->tm_hour -= HOURSPERDAY;
157
	  res->tm_hour -= HOURSPERDAY;
158
	  if (res->tm_mday > ip[res->tm_mon])
158
	  if (res->tm_mday > ip[res->tm_mon])
159
	    {
159
	    {
160
	      res->tm_mday -= ip[res->tm_mon];
160
	      res->tm_mday -= ip[res->tm_mon];
161
	      res->tm_mon += 1;
161
	      res->tm_mon += 1;
162
	      if (res->tm_mon == 12)
162
	      if (res->tm_mon == 12)
163
		{
163
		{
164
		  res->tm_mon = 0;
164
		  res->tm_mon = 0;
165
		  res->tm_year += 1;
165
		  res->tm_year += 1;
166
		  res->tm_yday = 0;
166
		  res->tm_yday = 0;
167
		}
167
		}
168
	    }
168
	    }
169
	}
169
	}
170
       else if (res->tm_hour < 0)
170
       else if (res->tm_hour < 0)
171
	{
171
	{
172
	  res->tm_yday -= 1;
172
	  res->tm_yday -= 1;
173
	  res->tm_wday -= 1;
173
	  res->tm_wday -= 1;
174
	  if (res->tm_wday < 0)
174
	  if (res->tm_wday < 0)
175
	    res->tm_wday = 6;
175
	    res->tm_wday = 6;
176
	  res->tm_mday -= 1;
176
	  res->tm_mday -= 1;
177
	  res->tm_hour += 24;
177
	  res->tm_hour += 24;
178
	  if (res->tm_mday == 0)
178
	  if (res->tm_mday == 0)
179
	    {
179
	    {
180
	      res->tm_mon -= 1;
180
	      res->tm_mon -= 1;
181
	      if (res->tm_mon < 0)
181
	      if (res->tm_mon < 0)
182
		{
182
		{
183
		  res->tm_mon = 11;
183
		  res->tm_mon = 11;
184
		  res->tm_year -= 1;
184
		  res->tm_year -= 1;
185
		  res->tm_yday = 365 + isleap(res->tm_year);
185
		  res->tm_yday = 364 + isleap(res->tm_year + 1900);
186
		}
186
		}
187
	      res->tm_mday = ip[res->tm_mon];
187
	      res->tm_mday = ip[res->tm_mon];
188
	    }
188
	    }
189
	}
189
	}
190
      TZ_UNLOCK;
190
      TZ_UNLOCK;
191
    }
191
    }
192
  else
192
  else
193
    res->tm_isdst = 0;
193
    res->tm_isdst = 0;
194
 
194
 
195
  return (res);
195
  return (res);
196
}
196
}
197
 
197
 
198
int
198
int
199
_DEFUN (__tzcalc_limits, (year),
199
_DEFUN (__tzcalc_limits, (year),
200
	int year)
200
	int year)
201
{
201
{
202
  int days, year_days, years;
202
  int days, year_days, years;
203
  int i, j;
203
  int i, j;
204
  __tzinfo_type *tz = __gettzinfo ();
204
  __tzinfo_type *tz = __gettzinfo ();
205
 
205
 
206
  if (year < EPOCH_YEAR)
206
  if (year < EPOCH_YEAR)
207
    return 0;
207
    return 0;
208
 
208
 
209
  tz->__tzyear = year;
209
  tz->__tzyear = year;
210
 
210
 
211
  years = (year - EPOCH_YEAR);
211
  years = (year - EPOCH_YEAR);
212
 
212
 
213
  year_days = years * 365 +
213
  year_days = years * 365 +
214
    (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + 
214
    (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + 
215
    (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400;
215
    (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400;
216
  
216
  
217
  for (i = 0; i < 2; ++i)
217
  for (i = 0; i < 2; ++i)
218
    {
218
    {
219
      if (tz->__tzrule[i].ch == 'J')
219
	if (tz->__tzrule[i].ch == 'J') {
-
 
220
        /* The Julian day n (1 <= n <= 365). */
220
	days = year_days + tz->__tzrule[i].d + 
221
	days = year_days + tz->__tzrule[i].d + 
221
		(isleap(year) && tz->__tzrule[i].d >= 60);
222
		(isleap(year) && tz->__tzrule[i].d >= 60);
-
 
223
        /* Convert to yday */
-
 
224
        --days;
222
      else if (tz->__tzrule[i].ch == 'D')
225
	} else if (tz->__tzrule[i].ch == 'D')
223
	days = year_days + tz->__tzrule[i].d;
226
	days = year_days + tz->__tzrule[i].d;
224
      else
227
      else
225
	{
228
	{
226
	  int yleap = isleap(year);
229
	  int yleap = isleap(year);
227
	  int m_day, m_wday, wday_diff;
230
	  int m_day, m_wday, wday_diff;
228
	  _CONST int *ip = mon_lengths[yleap];
231
	  _CONST int *ip = mon_lengths[yleap];
229
 
232
 
230
	  days = year_days;
233
	  days = year_days;
231
 
234
 
232
	  for (j = 1; j < tz->__tzrule[i].m; ++j)
235
	  for (j = 1; j < tz->__tzrule[i].m; ++j)
233
	    days += ip[j-1];
236
	    days += ip[j-1];
234
 
237
 
235
	  m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK;
238
	  m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK;
236
	  
239
	  
237
	  wday_diff = tz->__tzrule[i].d - m_wday;
240
	  wday_diff = tz->__tzrule[i].d - m_wday;
238
	  if (wday_diff < 0)
241
	  if (wday_diff < 0)
239
	    wday_diff += DAYSPERWEEK;
242
	    wday_diff += DAYSPERWEEK;
240
	  m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff;
243
	  m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff;
241
 
244
 
242
	  while (m_day >= ip[j-1])
245
	  while (m_day >= ip[j-1])
243
	    m_day -= DAYSPERWEEK;
246
	    m_day -= DAYSPERWEEK;
244
 
247
 
245
	  days += m_day;
248
	  days += m_day;
246
	}
249
	}
247
 
250
 
248
      /* store the change-over time in GMT form by adding offset */
251
      /* store the change-over time in GMT form by adding offset */
249
      tz->__tzrule[i].change = days * SECSPERDAY + 
252
      tz->__tzrule[i].change = days * SECSPERDAY + 
250
	      			tz->__tzrule[i].s + tz->__tzrule[i].offset;
253
	      			tz->__tzrule[i].s + tz->__tzrule[i].offset;
251
    }
254
    }
252
 
255
 
253
  tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change);
256
  tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change);
254
 
257
 
255
  return 1;
258
  return 1;
256
}
259
}
257
-