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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [time/] [mktime.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
/*
2
 * mktime.c
3
 * Original Author:     G. Haley
4
 *
5
 * Converts the broken-down time, expressed as local time, in the structure
6
 * pointed to by tim_p into a calendar time value. The original values of the
7
 * tm_wday and tm_yday fields of the structure are ignored, and the original
8
 * values of the other fields have no restrictions. On successful completion
9
 * the fields of the structure are set to represent the specified calendar
10
 * time. Returns the specified calendar time. If the calendar time can not be
11
 * represented, returns the value (time_t) -1.
12
 */
13
 
14
/*
15
FUNCTION
16
<<mktime>>---convert time to arithmetic representation
17
 
18
INDEX
19
        mktime
20
 
21
ANSI_SYNOPSIS
22
        #include <time.h>
23
        time_t mktime(struct tm *<[timp]>);
24
 
25
TRAD_SYNOPSIS
26
        #include <time.h>
27
        time_t mktime(<[timp]>)
28
        struct tm *<[timp]>;
29
 
30
DESCRIPTION
31
<<mktime>> assumes the time at <[timp]> is a local time, and converts
32
its representation from the traditional representation defined by
33
<<struct tm>> into a representation suitable for arithmetic.
34
 
35
<<localtime>> is the inverse of <<mktime>>.
36
 
37
RETURNS
38
If the contents of the structure at <[timp]> do not form a valid
39
calendar time representation, the result is <<-1>>.  Otherwise, the
40
result is the time, converted to a <<time_t>> value.
41
 
42
PORTABILITY
43
ANSI C requires <<mktime>>.
44
 
45
<<mktime>> requires no supporting OS subroutines.
46
*/
47
 
48
#include <stdlib.h>
49
#include <time.h>
50
 
51
#define _SEC_IN_MINUTE 60
52
#define _SEC_IN_HOUR 3600
53
#define _SEC_IN_DAY 86400
54
 
55
static _CONST int DAYS_IN_MONTH[12] =
56
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
57
 
58
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
59
 
60
static _CONST int _DAYS_BEFORE_MONTH[12] =
61
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
62
 
63 56 joel
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
64
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
65 39 lampret
 
66
static void
67
validate_structure (tim_p)
68
     struct tm *tim_p;
69
{
70
  div_t res;
71
  int days_in_feb = 28;
72
 
73
  /* calculate time & date to account for out of range values */
74
  if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
75
    {
76
      res = div (tim_p->tm_sec, 60);
77
      tim_p->tm_min += res.quot;
78
      if ((tim_p->tm_sec = res.rem) < 0)
79 56 joel
        {
80
          tim_p->tm_sec += 60;
81
          --tim_p->tm_min;
82
        }
83 39 lampret
    }
84
 
85
  if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
86
    {
87
      res = div (tim_p->tm_min, 60);
88
      tim_p->tm_hour += res.quot;
89
      if ((tim_p->tm_min = res.rem) < 0)
90 56 joel
        {
91
          tim_p->tm_min += 60;
92
          --tim_p->tm_hour;
93
        }
94 39 lampret
    }
95
 
96
  if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
97
    {
98
      res = div (tim_p->tm_hour, 24);
99
      tim_p->tm_mday += res.quot;
100
      if ((tim_p->tm_hour = res.rem) < 0)
101 56 joel
        {
102
          tim_p->tm_hour += 24;
103
          --tim_p->tm_mday;
104
        }
105 39 lampret
    }
106
 
107
  if (tim_p->tm_mon > 11)
108
    {
109
      res = div (tim_p->tm_mon, 12);
110
      tim_p->tm_year += res.quot;
111
      if ((tim_p->tm_mon = res.rem) < 0)
112 56 joel
        {
113
          tim_p->tm_mon += 12;
114
          --tim_p->tm_year;
115
        }
116 39 lampret
    }
117
 
118
  if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
119
    days_in_feb = 29;
120
 
121 56 joel
  if (tim_p->tm_mday <= 0)
122 39 lampret
    {
123 56 joel
      while (tim_p->tm_mday <= 0)
124 39 lampret
        {
125
          if (--tim_p->tm_mon == -1)
126
            {
127
              tim_p->tm_year--;
128 56 joel
              tim_p->tm_mon = 11;
129 39 lampret
              days_in_feb =
130
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
131
                 29 : 28);
132
            }
133 56 joel
          tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
134 39 lampret
        }
135
    }
136
  else
137
    {
138
      while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
139
        {
140
          tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
141
          if (++tim_p->tm_mon == 12)
142
            {
143
              tim_p->tm_year++;
144
              tim_p->tm_mon = 0;
145
              days_in_feb =
146
                ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
147
                 29 : 28);
148
            }
149
        }
150
    }
151
}
152
 
153
time_t
154
mktime (tim_p)
155
     struct tm *tim_p;
156
{
157
  time_t tim = 0;
158
  long days = 0;
159
  int year;
160
 
161
  /* validate structure */
162
  validate_structure (tim_p);
163
 
164
  /* compute hours, minutes, seconds */
165
  tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
166
    (tim_p->tm_hour * _SEC_IN_HOUR);
167
 
168
  /* compute days in year */
169
  days += tim_p->tm_mday - 1;
170
  days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
171
  if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
172
    days++;
173
 
174
  /* compute day of the year */
175
  tim_p->tm_yday = days;
176
 
177
  if (tim_p->tm_year > 10000
178
      || tim_p->tm_year < -10000)
179
    {
180
      return (time_t) -1;
181
    }
182
 
183
  /* compute days in other years */
184
  if (tim_p->tm_year > 70)
185
    {
186
      for (year = 70; year < tim_p->tm_year; year++)
187
        days += _DAYS_IN_YEAR (year);
188
    }
189
  else if (tim_p->tm_year < 70)
190
    {
191
      for (year = 69; year > tim_p->tm_year; year--)
192
        days -= _DAYS_IN_YEAR (year);
193
      days -= _DAYS_IN_YEAR (year);
194
    }
195
 
196
  /* compute day of the week */
197
  if ((tim_p->tm_wday = (days + 4) % 7) < 0)
198
    tim_p->tm_wday += 7;
199
 
200
  /* compute total seconds */
201
  tim += (days * _SEC_IN_DAY);
202
 
203
  return tim;
204
}

powered by: WebSVN 2.1.0

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