OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [time/] [mktm_r.c] - Blame information for rev 9

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.