📄 time.inl
字号:
#ifndef CYGONCE_LIBC_TIME_INL#define CYGONCE_LIBC_TIME_INL//===========================================================================//// time.inl//// Inline implementations of date and time routines from <time.h>////===========================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//===========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): jlarmour// Contributors: jlarmour// Date: 1999-02-25// Purpose: Provide inline implementations for some of the date and time// routines declared in <time.h> for ISO C section 7.12 and// POSIX 1003.1 8.3.4-8.3.7// Description: // Usage: Do not include this file directly. Instead include <time.h>////####DESCRIPTIONEND####////===========================================================================// CONFIGURATION#include <pkgconf/libc.h> // C library configuration// INCLUDES#include <cyg/infra/cyg_type.h> // Common type definitions and support#include <time.h> // Header for this file#include <cyg/infra/cyg_ass.h> // Assertion infrastructure#include <cyg/infra/cyg_trac.h> // Tracing infrastructure// DEFINES// The following are overriden by the libc implementation to get a non-inline// version to prevent duplication of code#ifndef CYGPRI_LIBC_TIME_ASCTIME_R_INLINE# define CYGPRI_LIBC_TIME_ASCTIME_R_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_CTIME_R_INLINE# define CYGPRI_LIBC_TIME_CTIME_R_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_GMTIME_R_INLINE# define CYGPRI_LIBC_TIME_GMTIME_R_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE# define CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_DIFFTIME_INLINE# define CYGPRI_LIBC_TIME_DIFFTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_MKTIME_INLINE# define CYGPRI_LIBC_TIME_MKTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_ASCTIME_INLINE# define CYGPRI_LIBC_TIME_ASCTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_CTIME_INLINE# define CYGPRI_LIBC_TIME_CTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_GMTIME_INLINE# define CYGPRI_LIBC_TIME_GMTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_LOCALTIME_INLINE# define CYGPRI_LIBC_TIME_LOCALTIME_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE# define CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE# define CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE extern __inline__#endif#ifndef CYGPRI_LIBC_TIME_SETDST_INLINE# define CYGPRI_LIBC_TIME_SETDST_INLINE extern __inline__#endif#define CYGNUM_LIBC_TIME_EPOCH_WDAY 4 // Jan 1st 1970 was a Thursday#ifdef __cplusplusextern "C" {#endif// EXTERNS// These are used in the dst access functions below. Do not access these// directly - use the functions declared in time.h insteadextern Cyg_libc_time_dst cyg_libc_time_current_dst_stat;extern time_t cyg_libc_time_current_std_offset;extern time_t cyg_libc_time_current_dst_offset;// INLINE FUNCTIONS//===========================================================================//// Utility functions//////////////////////////////////// cyg_libc_time_year_is_leap() //////////////////////////////////////// This returns true if the year is a leap year.// The argument is of type int in line with struct tm//static __inline__ cyg_boolcyg_libc_time_year_is_leap( int __year ){ cyg_bool _leap=false; if (!(__year % 400)) _leap = true; else if (!(__year % 4) && (__year % 100)) _leap = true; return _leap;} // cyg_libc_time_year_is_leap()////////////////////////////////////// cyg_libc_time_getzoneoffsets() ////////////////////////////////////////// This function retrieves the current state of the Daylight Savings Time// and the offsets of both STD and DST// The offsets are both in time_t's i.e. seconds//CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE Cyg_libc_time_dstcyg_libc_time_getzoneoffsets( time_t *__stdoffset, time_t *__dstoffset ){ CYG_REPORT_FUNCNAMETYPE("cyg_libc_time_getzoneoffsets", "returning DST state %d"); CYG_REPORT_FUNCARG2("__stdoffset is at address %08x, " "__dstoffset is at %08x", __stdoffset, __dstoffset); CYG_CHECK_DATA_PTR(__stdoffset, "__stdoffset is not a valid pointer!"); CYG_CHECK_DATA_PTR(__dstoffset, "__dstoffset is not a valid pointer!"); *__stdoffset = cyg_libc_time_current_std_offset; *__dstoffset = cyg_libc_time_current_dst_offset; CYG_REPORT_RETVAL(cyg_libc_time_current_dst_stat); return cyg_libc_time_current_dst_stat;} // cyg_libc_time_getzoneoffsets()////////////////////////////////////// cyg_libc_time_setzoneoffsets() ////////////////////////////////////////// This function sets the offsets used when Daylight Savings Time is enabled// or disabled. The offsets are in time_t's i.e. seconds//CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE voidcyg_libc_time_setzoneoffsets( time_t __stdoffset, time_t __dstoffset ){ CYG_REPORT_FUNCNAME("cyg_libc_time_setzoneoffsets"); CYG_REPORT_FUNCARG2DV(__stdoffset, __dstoffset); cyg_libc_time_current_std_offset = __stdoffset; cyg_libc_time_current_dst_offset = __dstoffset; CYG_REPORT_RETURN();} // cyg_libc_time_setzoneoffsets()////////////////////////////// cyg_libc_time_setdst() ////////////////////////////////// This function sets the state of Daylight Savings Time: on, off, or unknown//CYGPRI_LIBC_TIME_SETDST_INLINE voidcyg_libc_time_setdst( Cyg_libc_time_dst __state ){ CYG_REPORT_FUNCNAME("cyg_libc_time_setdst"); CYG_REPORT_FUNCARG1("__state=%d", __state); cyg_libc_time_current_dst_stat = __state; CYG_REPORT_RETURN();} // cyg_libc_time_setdst()//===========================================================================//// POSIX 1003.1 functions/////////////////////////////////// asctime_r() - POSIX.1 8.3.4 /////////////////////////////////////// This returns a textual representation of a struct tm, and writes// the string to return into __buf//#ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE#include <stdio.h> // for sprintf()#include <sys/timeutil.h> // for cyg_libc_time_{day,month}_name#include <string.h> // for memcpy()#include <stdlib.h> // for cyg_libc_itoa()CYGPRI_LIBC_TIME_ASCTIME_R_INLINE char *__asctime_r( const struct tm *__timeptr, char *__buf ){ cyg_uint8 __i; // These initializers are [4] since C++ dictates you _must_ leave space // for the trailing '\0', even though ISO C says you don't need to! CYG_REPORT_FUNCNAMETYPE("__asctime_r", "returning \"%s\""); CYG_REPORT_FUNCARG2("__timeptr = %08x, __buf = %08x", __timeptr, __buf); // paranoia - most of these aren't required but could be helpful to // a programmer debugging their own app. CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); CYG_CHECK_DATA_PTR(__buf, "__buf is not a valid pointer!"); CYG_PRECONDITION((__timeptr->tm_sec >= 0) && (__timeptr->tm_sec < 62), "__timeptr->tm_sec out of range!"); CYG_PRECONDITION((__timeptr->tm_min >= 0) && (__timeptr->tm_min < 60), "__timeptr->tm_min out of range!"); CYG_PRECONDITION((__timeptr->tm_hour >= 0) && (__timeptr->tm_hour < 24), "__timeptr->tm_hour out of range!"); // Currently I don't check _actual_ numbers of days in each month here // FIXME: No reason why not though CYG_PRECONDITION((__timeptr->tm_mday >= 1) && (__timeptr->tm_mday < 32), "__timeptr->tm_mday out of range!"); CYG_PRECONDITION((__timeptr->tm_mon >= 0) && (__timeptr->tm_mon < 12), "__timeptr->tm_mon out of range!"); CYG_PRECONDITION((__timeptr->tm_wday >= 0) && (__timeptr->tm_wday < 7), "__timeptr->tm_wday out of range!"); CYG_PRECONDITION((__timeptr->tm_yday >= 0) && (__timeptr->tm_yday < 366), "__timeptr->tm_yday out of range!"); CYG_PRECONDITION((__timeptr->tm_year > -1900) && (__timeptr->tm_year < 8100), "__timeptr->tm_year out of range!"); // we can't use strftime because ISO C is stupid enough not to allow // the strings in asctime() to be localized. Duh. // day of the week memcpy(&__buf[0], cyg_libc_time_day_name[__timeptr->tm_wday], 3); __buf[3] = ' '; // month memcpy(&__buf[4], cyg_libc_time_month_name[__timeptr->tm_mon], 3); __buf[7] = ' '; __i = 8; // day of the month __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_mday, 2, true); __buf[__i++] = ' '; // hour __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_hour, 2, true); __buf[__i++] = ':'; // minute __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_min, 2, true); __buf[__i++] = ':'; // second __i += cyg_libc_itoa((cyg_uint8 *) &__buf[__i], __timeptr->tm_sec, 2, true); __buf[__i++] = ' '; // year __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], 1900+__timeptr->tm_year, 0, true); __buf[__i++] = '\n'; __buf[__i++] = '\0'; CYG_REPORT_RETVAL(__buf); return __buf;} // __asctime_r()# ifdef CYGFUN_LIBC_TIME_POSIX# define asctime_r(__timeptr, __buf) __asctime_r(__timeptr, __buf)# endif#elseextern char *__asctime_r( const struct tm *__timeptr, char *__buf );#endif // ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE////////////////////////////////// gmtime_r() - POSIX.1 8.3.6 ////////////////////////////////////// This converts a time_t into a struct tm expressed in UTC, and stores// the result in the space occupied by __result//#ifdef CYGIMP_LIBC_TIME_GMTIME_R_INLINE#include <sys/timeutil.h> // for cyg_libc_time_month_lengthsCYGPRI_LIBC_TIME_GMTIME_R_INLINE struct tm *__gmtime_r( const time_t *__timer, struct tm *__result ){ time_t _tim; const cyg_uint8 *_months_p; CYG_REPORT_FUNCNAMETYPE("__gmtime_r", "returning %08x"); CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); CYG_CHECK_DATA_PTR(__result, "__result is not a valid pointer!"); CYG_REPORT_FUNCARG2("*__timer=%d, __result is at %08x", *__timer, __result);#define CYGNUM_LIBC_TIME_SECSPERDAY (60*60*24)#define CYGNUM_LIBC_TIME_SECSPERYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 365)#define CYGNUM_LIBC_TIME_SECSPERLEAPYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 366) _tim = *__timer; // First, work out year. Start off with 1970 and work forwards or backwards // depending on the sign of _tim __result->tm_year = 70; // we also work out the day of the week of the start of the year as we // go along __result->tm_wday = CYGNUM_LIBC_TIME_EPOCH_WDAY; while (_tim < 0) { // Work backwards --__result->tm_year; // Check for a leap year. if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { _tim += CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; __result->tm_wday -= 366; } // if else { _tim += CYGNUM_LIBC_TIME_SECSPERYEAR; __result->tm_wday -= 365; } // else } // while while (_tim >= CYGNUM_LIBC_TIME_SECSPERYEAR) { // Work forwards if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { // But if this is a leap year, its possible that we are in the // middle of the last "extra" day if (_tim < CYGNUM_LIBC_TIME_SECSPERLEAPYEAR) break; _tim -= CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; __result->tm_wday += 366; } // if else { _tim -= CYGNUM_LIBC_TIME_SECSPERYEAR; __result->tm_wday += 365; } ++__result->tm_year; } // while // Day of the year. We know _tim is +ve now CYG_ASSERT(_tim >= 0, "Number of seconds since start of year is negative!"); // assign tm_mday as well for further below __result->tm_mday = __result->tm_yday = _tim / CYGNUM_LIBC_TIME_SECSPERDAY; // Day of the week. Normalize to be 0..6, and note that it might // be negative, so we have to deal with the modulus being // implementation-defined for -ve numbers (ISO C 6.3.5) __result->tm_wday = (((__result->tm_wday + __result->tm_yday)%7)+7)%7; // Month and Day of the month _months_p = cyg_libc_time_month_lengths[ cyg_libc_time_year_is_leap(1900 + __result->tm_year)];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -