source: EcnlProtoTool/trunk/ntshell/fatfs/time.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 6.5 KB
Line 
1/* musl-1.1.12/src/time/*.c */
2/* musl as a whole is licensed under the following standard MIT license:
3*
4* ----------------------------------------------------------------------
5* Copyright (C) 2005-2014 Rich Felker, et al.
6*
7* Permission is hereby granted, free of charge, to any person obtaining
8* a copy of this software and associated documentation files (the
9* "Software"), to deal in the Software without restriction, including
10* without limitation the rights to use, copy, modify, merge, publish,
11* distribute, sublicense, and/or sell copies of the Software, and to
12* permit persons to whom the Software is furnished to do so, subject to
13* the following conditions:
14*
15* The above copyright notice and this permission notice shall be
16* included in all copies or substantial portions of the Software.
17*
18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25* ----------------------------------------------------------------------*/
26#include <string.h>
27#include <limits.h>
28#include <time.h>
29#include <errno.h>
30#include "ff.h"
31
32/* 2000-03-01 (mod 400 year, immediately after feb29 */
33#define LEAPOCH (946684800LL + 86400*(31+29))
34
35#define DAYS_PER_400Y (365*400 + 97)
36#define DAYS_PER_100Y (365*100 + 24)
37#define DAYS_PER_4Y (365*4 + 1)
38
39int __secs_to_tm(long long t, struct tm* tm)
40{
41 long long days, secs, years;
42 int remdays, remsecs, remyears;
43 int qc_cycles, c_cycles, q_cycles;
44 int months;
45 int wday, yday, leap;
46 static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
47
48 /* Reject time_t values whose year would overflow int */
49 if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
50 return -1;
51
52 secs = t - LEAPOCH;
53 days = secs / 86400;
54 remsecs = secs % 86400;
55 if (remsecs < 0) {
56 remsecs += 86400;
57 days--;
58 }
59
60 wday = (3 + days) % 7;
61 if (wday < 0) wday += 7;
62
63 qc_cycles = days / DAYS_PER_400Y;
64 remdays = days % DAYS_PER_400Y;
65 if (remdays < 0) {
66 remdays += DAYS_PER_400Y;
67 qc_cycles--;
68 }
69
70 c_cycles = remdays / DAYS_PER_100Y;
71 if (c_cycles == 4) c_cycles--;
72 remdays -= c_cycles * DAYS_PER_100Y;
73
74 q_cycles = remdays / DAYS_PER_4Y;
75 if (q_cycles == 25) q_cycles--;
76 remdays -= q_cycles * DAYS_PER_4Y;
77
78 remyears = remdays / 365;
79 if (remyears == 4) remyears--;
80 remdays -= remyears * 365;
81
82 leap = !remyears && (q_cycles || !c_cycles);
83 yday = remdays + 31 + 28 + leap;
84 if (yday >= 365 + leap) yday -= 365 + leap;
85
86 years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;
87
88 for (months = 0; days_in_month[months] <= remdays; months++)
89 remdays -= days_in_month[months];
90
91 if (years + 100 > INT_MAX || years + 100 < INT_MIN)
92 return -1;
93
94 tm->tm_year = years + 100;
95 tm->tm_mon = months + 2;
96 if (tm->tm_mon >= 12) {
97 tm->tm_mon -= 12;
98 tm->tm_year++;
99 }
100 tm->tm_mday = remdays + 1;
101 tm->tm_wday = wday;
102 tm->tm_yday = yday;
103
104 tm->tm_hour = remsecs / 3600;
105 tm->tm_min = remsecs / 60 % 60;
106 tm->tm_sec = remsecs % 60;
107
108 return 0;
109}
110
111long long __year_to_secs(long long year, int *is_leap)
112{
113 if (year - 2ULL <= 136) {
114 int y = year;
115 int leaps = (y - 68) >> 2;
116 if (!((y - 68) & 3)) {
117 leaps--;
118 if (is_leap) *is_leap = 1;
119 }
120 else if (is_leap) *is_leap = 0;
121 return 31536000 * (y - 70) + 86400 * leaps;
122 }
123
124 int cycles, centuries, leaps, rem;
125
126 if (!is_leap) is_leap = &(int) { 0 };
127 cycles = (year - 100) / 400;
128 rem = (year - 100) % 400;
129 if (rem < 0) {
130 cycles--;
131 rem += 400;
132 }
133 if (!rem) {
134 *is_leap = 1;
135 centuries = 0;
136 leaps = 0;
137 }
138 else {
139 if (rem >= 200) {
140 if (rem >= 300) centuries = 3, rem -= 300;
141 else centuries = 2, rem -= 200;
142 }
143 else {
144 if (rem >= 100) centuries = 1, rem -= 100;
145 else centuries = 0;
146 }
147 if (!rem) {
148 *is_leap = 0;
149 leaps = 0;
150 }
151 else {
152 leaps = rem / 4U;
153 rem %= 4U;
154 *is_leap = !rem;
155 }
156 }
157
158 leaps += 97 * cycles + 24 * centuries - *is_leap;
159
160 return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
161}
162
163int __month_to_secs(int month, int is_leap)
164{
165 static const int secs_through_month[] = {
166 0, 31 * 86400, 59 * 86400, 90 * 86400,
167 120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
168 243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400};
169 int t = secs_through_month[month];
170 if (is_leap && month >= 2) t += 86400;
171 return t;
172}
173
174long long __tm_to_secs(const struct tm *tm)
175{
176 int is_leap;
177 long long year = tm->tm_year;
178 int month = tm->tm_mon;
179 if (month >= 12 || month < 0) {
180 int adj = month / 12;
181 month %= 12;
182 if (month < 0) {
183 adj--;
184 month += 12;
185 }
186 year += adj;
187 }
188 long long t = __year_to_secs(year, &is_leap);
189 t += __month_to_secs(month, is_leap);
190 t += 86400LL * (tm->tm_mday - 1);
191 t += 3600LL * tm->tm_hour;
192 t += 60LL * tm->tm_min;
193 t += tm->tm_sec;
194 return t;
195}
196
197struct tm *localtime_r(const time_t *t, struct tm *tm)
198{
199 /* Reject time_t values whose year would overflow int because
200 * __secs_to_zone cannot safely handle them. */
201 if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
202 errno = EOVERFLOW;
203 return 0;
204 }
205 //TODO:__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
206 if (__secs_to_tm((long long)*t /*+ tm->__tm_gmtoff*/, tm) < 0) {
207 errno = EOVERFLOW;
208 return 0;
209 }
210 return tm;
211}
212
213struct tm *localtime(const time_t *time)
214{
215 static struct tm tm;
216 return localtime_r(time, &tm);
217}
218
219struct tm *gmtime_r(const time_t *t, struct tm *tm)
220{
221 if (__secs_to_tm(*t, tm) < 0) {
222 errno = EOVERFLOW;
223 return 0;
224 }
225 tm->tm_isdst = 0;
226 /*tm->__tm_gmtoff = 0;
227 tm->__tm_zone = NULL;//__gmt;*/
228 return tm;
229}
230
231/* There is no other implemented value than TIME_UTC; all other values
232 * are considered erroneous. */
233/*int timespec_get(struct timespec * ts, int base)
234{
235 if (base != TIME_UTC) return 0;
236 int ret = __clock_gettime(CLOCK_REALTIME, ts);
237 return ret < 0 ? 0 : base;
238}*/
239time_t mktime(struct tm *tm)
240{
241 struct tm new;
242 long opp;
243 long long t = __tm_to_secs(tm);
244
245 if (__secs_to_tm(t, &new) < 0) goto error;
246
247 *tm = new;
248 return t;
249
250error:
251 errno = EOVERFLOW;
252 return -1;
253}
254
255DWORD get_fattime(void)
256{
257 time_t temp;
258 struct tm _tm;
259
260 time(&temp);
261 gmtime_r(&temp, &_tm);
262
263 return ((DWORD)(_tm.tm_year - 1980) << 25)
264 | ((DWORD)_tm.tm_mon << 21)
265 | ((DWORD)_tm.tm_mday << 16)
266 | ((DWORD)_tm.tm_hour << 11)
267 | ((DWORD)_tm.tm_min << 5)
268 | ((DWORD)_tm.tm_sec >> 1);
269}
Note: See TracBrowser for help on using the repository browser.