source: EcnlProtoTool/trunk/ntshell/fatfs/fftime.c@ 331

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • 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
32int shell_errno;
33
34/* 2000-03-01 (mod 400 year, immediately after feb29 */
35#define LEAPOCH (946684800LL + 86400*(31+29))
36
37#define DAYS_PER_400Y (365*400 + 97)
38#define DAYS_PER_100Y (365*100 + 24)
39#define DAYS_PER_4Y (365*4 + 1)
40
41int __secs_to_tm(long long t, struct tm* tm)
42{
43 long long days, secs, years;
44 int remdays, remsecs, remyears;
45 int qc_cycles, c_cycles, q_cycles;
46 int months;
47 int wday, yday, leap;
48 static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
49
50 /* Reject time_t values whose year would overflow int */
51 if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
52 return -1;
53
54 secs = t - LEAPOCH;
55 days = secs / 86400;
56 remsecs = secs % 86400;
57 if (remsecs < 0) {
58 remsecs += 86400;
59 days--;
60 }
61
62 wday = (3 + days) % 7;
63 if (wday < 0) wday += 7;
64
65 qc_cycles = days / DAYS_PER_400Y;
66 remdays = days % DAYS_PER_400Y;
67 if (remdays < 0) {
68 remdays += DAYS_PER_400Y;
69 qc_cycles--;
70 }
71
72 c_cycles = remdays / DAYS_PER_100Y;
73 if (c_cycles == 4) c_cycles--;
74 remdays -= c_cycles * DAYS_PER_100Y;
75
76 q_cycles = remdays / DAYS_PER_4Y;
77 if (q_cycles == 25) q_cycles--;
78 remdays -= q_cycles * DAYS_PER_4Y;
79
80 remyears = remdays / 365;
81 if (remyears == 4) remyears--;
82 remdays -= remyears * 365;
83
84 leap = !remyears && (q_cycles || !c_cycles);
85 yday = remdays + 31 + 28 + leap;
86 if (yday >= 365 + leap) yday -= 365 + leap;
87
88 years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;
89
90 for (months = 0; days_in_month[months] <= remdays; months++)
91 remdays -= days_in_month[months];
92
93 if (years + 100 > INT_MAX || years + 100 < INT_MIN)
94 return -1;
95
96 tm->tm_year = years + 100;
97 tm->tm_mon = months + 2;
98 if (tm->tm_mon >= 12) {
99 tm->tm_mon -= 12;
100 tm->tm_year++;
101 }
102 tm->tm_mday = remdays + 1;
103 tm->tm_wday = wday;
104 tm->tm_yday = yday;
105
106 tm->tm_hour = remsecs / 3600;
107 tm->tm_min = remsecs / 60 % 60;
108 tm->tm_sec = remsecs % 60;
109
110 return 0;
111}
112
113long long __year_to_secs(long long year, int *is_leap)
114{
115 if (year - 2ULL <= 136) {
116 int y = year;
117 int leaps = (y - 68) >> 2;
118 if (!((y - 68) & 3)) {
119 leaps--;
120 if (is_leap) *is_leap = 1;
121 }
122 else if (is_leap) *is_leap = 0;
123 return 31536000 * (y - 70) + 86400 * leaps;
124 }
125
126 int cycles, centuries, leaps, rem;
127
128 if (!is_leap) is_leap = &(int) { 0 };
129 cycles = (year - 100) / 400;
130 rem = (year - 100) % 400;
131 if (rem < 0) {
132 cycles--;
133 rem += 400;
134 }
135 if (!rem) {
136 *is_leap = 1;
137 centuries = 0;
138 leaps = 0;
139 }
140 else {
141 if (rem >= 200) {
142 if (rem >= 300) centuries = 3, rem -= 300;
143 else centuries = 2, rem -= 200;
144 }
145 else {
146 if (rem >= 100) centuries = 1, rem -= 100;
147 else centuries = 0;
148 }
149 if (!rem) {
150 *is_leap = 0;
151 leaps = 0;
152 }
153 else {
154 leaps = rem / 4U;
155 rem %= 4U;
156 *is_leap = !rem;
157 }
158 }
159
160 leaps += 97 * cycles + 24 * centuries - *is_leap;
161
162 return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
163}
164
165int __month_to_secs(int month, int is_leap)
166{
167 static const int secs_through_month[] = {
168 0, 31 * 86400, 59 * 86400, 90 * 86400,
169 120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
170 243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400};
171 int t = secs_through_month[month];
172 if (is_leap && month >= 2) t += 86400;
173 return t;
174}
175
176long long __tm_to_secs(const struct tm *tm)
177{
178 int is_leap;
179 long long year = tm->tm_year;
180 int month = tm->tm_mon;
181 if (month >= 12 || month < 0) {
182 int adj = month / 12;
183 month %= 12;
184 if (month < 0) {
185 adj--;
186 month += 12;
187 }
188 year += adj;
189 }
190 long long t = __year_to_secs(year, &is_leap);
191 t += __month_to_secs(month, is_leap);
192 t += 86400LL * (tm->tm_mday - 1);
193 t += 3600LL * tm->tm_hour;
194 t += 60LL * tm->tm_min;
195 t += tm->tm_sec;
196 return t;
197}
198
199struct tm *localtime_r(const time_t *t, struct tm *tm)
200{
201 /* Reject time_t values whose year would overflow int because
202 * __secs_to_zone cannot safely handle them. */
203 if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
204 shell_errno = EOVERFLOW;
205 return 0;
206 }
207 //TODO:__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
208 if (__secs_to_tm((long long)*t /*+ tm->__tm_gmtoff*/, tm) < 0) {
209 shell_errno = EOVERFLOW;
210 return 0;
211 }
212 return tm;
213}
214
215struct tm *localtime(const time_t *time)
216{
217 static struct tm tm;
218 return localtime_r(time, &tm);
219}
220
221struct tm *gmtime_r(const time_t *t, struct tm *tm)
222{
223 if (__secs_to_tm(*t, tm) < 0) {
224 shell_errno = EOVERFLOW;
225 return 0;
226 }
227 tm->tm_isdst = 0;
228 /*tm->__tm_gmtoff = 0;
229 tm->__tm_zone = NULL;//__gmt;*/
230 return tm;
231}
232
233/* There is no other implemented value than TIME_UTC; all other values
234 * are considered erroneous. */
235/*int timespec_get(struct timespec * ts, int base)
236{
237 if (base != TIME_UTC) return 0;
238 int ret = __clock_gettime(CLOCK_REALTIME, ts);
239 return ret < 0 ? 0 : base;
240}*/
241time_t mktime(struct tm *tm)
242{
243 struct tm new;
244 long opp;
245 long long t = __tm_to_secs(tm);
246
247 if (__secs_to_tm(t, &new) < 0) goto error;
248
249 *tm = new;
250 return t;
251
252error:
253 shell_errno = EOVERFLOW;
254 return -1;
255}
256
257DWORD get_fattime(void)
258{
259 time_t temp;
260 struct tm _tm;
261
262 temp = rtc_read();
263 gmtime_r(&temp, &_tm);
264
265 return ((DWORD)(_tm.tm_year - 1980) << 25)
266 | ((DWORD)_tm.tm_mon << 21)
267 | ((DWORD)_tm.tm_mday << 16)
268 | ((DWORD)_tm.tm_hour << 11)
269 | ((DWORD)_tm.tm_min << 5)
270 | ((DWORD)_tm.tm_sec >> 1);
271}
Note: See TracBrowser for help on using the repository browser.