📄 time.c
字号:
off -= 3600; /* Default to 1 hour ahead of std. */ goto SKIP_OFFSET; } --e; } ++e; if (!(e = getoffset(e, &off))) { goto ILLEGAL; } if (*s == '-') { off = -off; /* Save off in case needed for dst default. */ } SKIP_OFFSET: new_rules[count].gmt_offset = off; if (!count) { new_rules[1].gmt_offset = off; /* Shouldn't be needed... */ if (*e) { ++count; goto LOOP; } } else { /* OK, we have dst, so get some rules. */ count = 0; if (!*e) { /* No rules so default to US rules. */ e = DEFAULT_RULES; } do { if (*e++ != ',') { goto ILLEGAL; } n = 365; s = (char *) RULE; if ((c = *e++) == 'M') { n = 12; } else if (c == 'J') { s += 8; } else { --e; c = 0; s += 6; } *(p = &new_rules[count].rule_type) = c; if (c != 'M') { p -= 2; } do { ++s; if (!(e = getnumber(e, &f)) || (((unsigned int)(f - s[1])) > n) || (*s && (*e++ != *s)) ) { goto ILLEGAL; } *--p = f; } while ((n = *(s += 2)) > 0); off = 2 * 60 * 60; /* Default to 2:00:00 */ if (*e == '/') { ++e; if (!(e = getoffset(e, &off))) { goto ILLEGAL; } } new_rules[count].dst_offset = off; } while (++count < 2); if (*e) { goto ILLEGAL; } } memcpy(_time_tzinfo, new_rules, sizeof(new_rules)); DONE: tzname[0] = _time_tzinfo[0].tzname; tzname[1] = _time_tzinfo[1].tzname; daylight = !!_time_tzinfo[1].tzname[0]; timezone = _time_tzinfo[0].gmt_offset;#if defined(__UCLIBC_HAS_TZ_FILE__) FAST_DONE:#endif TZUNLOCK;}#endif/**********************************************************************//* #ifdef L_utime *//* utime is a syscall in both linux and elks. *//* int utime(const char *path, const struct utimbuf *times) *//* #endif *//**********************************************************************//* Non-SUSv3 *//**********************************************************************/#ifdef L_utimes#ifndef __BCC__#error The uClibc version of utimes is in sysdeps/linux/common.#endif#include <utime.h>#include <sys/time.h>int utimes(const char *filename, register const struct timeval *tvp){ register struct utimbuf *p = NULL; struct utimbuf utb; if (tvp) { p = &utb; p->actime = tvp[0].tv_sec; p->modtime = tvp[1].tv_sec; } return utime(filename, p);}#endif/**********************************************************************/#ifdef L__time_t2tmstatic const uint16_t vals[] = { 60, 60, 24, 7 /* special */, 36524, 1461, 365, 0};static const unsigned char days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* non-leap */ 29,};#ifdef __UCLIBC_HAS_TM_EXTENSIONS__static const char utc_string[] = "UTC";#endif/* Notes: * If time_t is 32 bits, then no overflow is possible. * It time_t is > 32 bits, this needs to be adjusted to deal with overflow. *//* Note: offset is the correction in _days_ to *timer! */struct tm *_time_t2tm(const time_t *__restrict timer, int offset, struct tm *__restrict result){ register int *p; time_t t1, t, v; int wday; /* Note: wday can be uninitialized. */ { register const uint16_t *vp; t = *timer; p = (int *) result; p[7] = 0; vp = vals; do { if ((v = *vp) == 7) { /* Overflow checking, assuming time_t is long int... */#if (LONG_MAX > INT_MAX) && (LONG_MAX > 2147483647L)#if (INT_MAX == 2147483647L) && (LONG_MAX == 9223372036854775807L) /* Valid range for t is [-784223472856L, 784223421720L]. * Outside of this range, the tm_year field will overflow. */ if (((unsigned long)(t + offset- -784223472856L)) > (784223421720L - -784223472856L) ) { return NULL; }#else#error overflow conditions unknown#endif#endif /* We have days since the epoch, so caluclate the weekday. */#if defined(__BCC__) && TIME_T_IS_UNSIGNED wday = (t + 4) % (*vp); /* t is unsigned */#else wday = ((int)((t % (*vp)) + 11)) % ((int)(*vp)); /* help bcc */#endif /* Set divisor to days in 400 years. Be kind to bcc... */ v = ((time_t)(vp[1])) << 2; ++v; /* Change to days since 1/1/1601 so that for 32 bit time_t * values, we'll have t >= 0. This should be changed for * archs with larger time_t types. * Also, correct for offset since a multiple of 7. */ /* TODO: Does this still work on archs with time_t > 32 bits? */ t += (135140L - 366) + offset; /* 146097 - (365*30 + 7) -366 */ }#if defined(__BCC__) && TIME_T_IS_UNSIGNED t -= ((t1 = t / v) * v);#else if ((t -= ((t1 = t / v) * v)) < 0) { t += v; --t1; }#endif if ((*vp == 7) && (t == v-1)) { --t; /* Correct for 400th year leap case */ ++p[4]; /* Stash the extra day... */ }#if defined(__BCC__) && 0 *p = t1; if (v <= 60) { *p = t; t = t1; } ++p;#else if (v <= 60) { *p++ = t; t = t1; } else { *p++ = t1; }#endif } while (*++vp); } if (p[-1] == 4) { --p[-1]; t = 365; } *p += ((int) t); /* result[7] .. tm_yday */ p -= 2; /* at result[5] */#if (LONG_MAX > INT_MAX) && (LONG_MAX > 2147483647L) /* Protect against overflow. TODO: Unecessary if int arith wraps? */ *p = ((((p[-2]<<2) + p[-1])*25 + p[0])<< 2) + (p[1] - 299); /* tm_year */#else *p = ((((p[-2]<<2) + p[-1])*25 + p[0])<< 2) + p[1] - 299; /* tm_year */#endif p[1] = wday; /* result[6] .. tm_wday */ { register const unsigned char *d = days; wday = 1900 + *p; if (__isleap(wday)) { d += 11; } wday = p[2] + 1; /* result[7] .. tm_yday */ *--p = 0; /* at result[4] .. tm_mon */ while (wday > *d) { wday -= *d; if (*d == 29) { d -= 11; /* Backup to non-leap Feb. */ } ++d; ++*p; /* Increment tm_mon. */ } p[-1] = wday; /* result[3] .. tm_mday */ } /* TODO -- should this be 0? */ p[4] = 0; /* result[8] .. tm_isdst */#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ result->tm_gmtoff = 0; result->tm_zone = utc_string;#endif /* __UCLIBC_HAS_TM_EXTENSIONS__ */ return result;}#endif/**********************************************************************/#ifdef L___time_tmstruct tm __time_tm; /* Global shared by gmtime() and localtime(). */#endif/**********************************************************************/#ifdef L__time_mktimetime_t _time_mktime(struct tm *timeptr, int store_on_success){ time_t t; TZLOCK; tzset(); t = _time_mktime_tzi(timeptr, store_on_success, _time_tzinfo); TZUNLOCK; return t;}#endif/**********************************************************************/#ifdef L__time_mktime_tzistatic const unsigned char vals[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* non-leap */ 29,};time_t _time_mktime_tzi(struct tm *timeptr, int store_on_success, rule_struct *tzi){#ifdef __BCC__ long days, secs;#else long long secs;#endif time_t t; struct tm x; /* 0:sec 1:min 2:hour 3:mday 4:mon 5:year 6:wday 7:yday 8:isdst */ register int *p = (int *) &x; register const unsigned char *s; int d, default_dst; memcpy(p, timeptr, sizeof(struct tm)); if (!tzi[1].tzname[0]) { /* No dst in this timezone, */ p[8] = 0; /* so set tm_isdst to 0. */ } default_dst = 0; if (p[8]) { /* Either dst or unknown? */ default_dst = 1; /* Assume advancing (even if unknown). */ p[8] = ((p[8] > 0) ? 1 : -1); /* Normalize so abs() <= 1. */ } d = 400; p[5] = (p[5] - ((p[6] = p[5]/d) * d)) + (p[7] = p[4]/12); if ((p[4] -= 12 * p[7]) < 0) { p[4] += 12; --p[5]; } s = vals; d = (p[5] += 1900); /* Correct year. Now between 1900 and 2300. */ if (__isleap(d)) { s += 11; } p[7] = 0; d = p[4]; while (d) { p[7] += *s; if (*s == 29) { s -= 11; /* Backup to non-leap Feb. */ } ++s; --d; }#ifdef __BCC__ d = p[5] - 1; days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]); secs = p[0] + 60*( p[1] + 60*((long)(p[2])) ) + tzi[default_dst].gmt_offset; DST_CORRECT: if (secs < 0) { secs += 120009600L; days -= 1389; } if ( ((unsigned long)(days + secs/86400L)) > 49710L) { t = ((time_t)(-1)); goto DONE; } secs += (days * 86400L);#else d = p[5] - 1; d = -719163L + d*365 + (d/4) - (d/100) + (d/400); secs = p[0] + tzi[default_dst].gmt_offset + 60*( p[1] + 60*(p[2] + 24*(((146073L * ((long long)(p[6])) + d) + p[3]) + p[7]))); DST_CORRECT: if (((unsigned long long)(secs - LONG_MIN)) > (((unsigned long long)LONG_MAX) - LONG_MIN) ) { t = ((time_t)(-1)); goto DONE; }#endif d = ((struct tm *)p)->tm_isdst; t = secs; __time_localtime_tzi(&t, (struct tm *)p, tzi); if (t == ((time_t)(-1))) { /* Remember, time_t can be unsigned. */ goto DONE; } if ((d < 0) && (((struct tm *)p)->tm_isdst != default_dst)) {#ifdef __BCC__ secs -= (days * 86400L);#endif secs += (tzi[1-default_dst].gmt_offset - tzi[default_dst].gmt_offset); goto DST_CORRECT; } if (store_on_success) { memcpy(timeptr, p, sizeof(struct tm)); } DONE: return t;}#endif/**********************************************************************/#if defined(L_wcsftime) || defined(L_wcsftime_l)#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)extern size_t __wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, __const wchar_t *__restrict __format, __const struct tm *__restrict __timeptr, __locale_t __loc) __THROW;size_t wcsftime(wchar_t *__restrict s, size_t maxsize, const wchar_t *__restrict format, const struct tm *__restrict timeptr){ return __wcsftime_l(s, maxsize, format, timeptr, __UCLIBC_CURLOCALE);}#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */size_t __XL(wcsftime)(wchar_t *__restrict s, size_t maxsize, const wchar_t *__restrict format, const struct tm *__restrict timeptr __LOCALE_PARAM ){#warning wcsftime always fails return 0; /* always fail */}__XL_ALIAS(wcsftime)#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */#endif/**********************************************************************/#ifdef L_dysize/* Return the number of days in YEAR. */int dysize(int year){ return __isleap(year) ? 366 : 365;}#endif/**********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -