diff --git a/components/libc/Kconfig b/components/libc/Kconfig index ea6763007e..13de415726 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -3,11 +3,7 @@ menu "C/C++ and POSIX layer" config RT_USING_EXTERNAL_LIBC bool -config RT_LIBC_DEFAULT_TIMEZONE - int "Set the default time zone (UTC+)" - range -12 12 - default 8 - +source "$RTT_DIR/components/libc/compilers/common/Kconfig" source "$RTT_DIR/components/libc/posix/Kconfig" source "$RTT_DIR/components/libc/cplusplus/Kconfig" diff --git a/components/libc/compilers/common/Kconfig b/components/libc/compilers/common/Kconfig new file mode 100644 index 0000000000..164c46acd7 --- /dev/null +++ b/components/libc/compilers/common/Kconfig @@ -0,0 +1,26 @@ +menu "ISO-ANSI C layer" + +menu "Timezone and Daylight Saving Time" + config RT_LIBC_USING_LIGHT_TZ_DST + bool "Enable lightweight timezone and daylight saving time" + default y + + if RT_LIBC_USING_LIGHT_TZ_DST + config RT_LIBC_TZ_DEFAULT_HOUR + int "Set the default local timezone (hour)" + range -12 12 + default 8 + + config RT_LIBC_TZ_DEFAULT_MIN + int "Set the default local timezone (minute)" + range -59 59 + default 0 + + config RT_LIBC_TZ_DEFAULT_SEC + int "Set the default local timezone (second)" + range -59 59 + default 0 + endif +endmenu + +endmenu diff --git a/components/libc/compilers/common/ctime.c b/components/libc/compilers/common/ctime.c index e474ea8c12..5147d8c17c 100644 --- a/components/libc/compilers/common/ctime.c +++ b/components/libc/compilers/common/ctime.c @@ -22,6 +22,7 @@ * 2023-07-03 xqyjlj refactor posix time and timer * 2023-07-16 Shell update signal generation routine for lwp * adapt to new api and do the signal handling in thread context + * 2023-08-12 Meco Man re-implement RT-Thread lightweight timezone API */ #include "sys/time.h" @@ -115,6 +116,49 @@ static rt_err_t _control_rtc(int cmd, void *arg) #endif /* RT_USING_RTC */ } +/* lightweight timezone and daylight saving time */ +#ifdef RT_LIBC_USING_LIGHT_TZ_DST +#ifndef RT_LIBC_TZ_DEFAULT_HOUR +#define RT_LIBC_TZ_DEFAULT_HOUR (8U) +#endif /* RT_LIBC_TZ_DEFAULT_HOUR */ + +#ifndef RT_LIBC_TZ_DEFAULT_MIN +#define RT_LIBC_TZ_DEFAULT_MIN (0U) +#endif /* RT_LIBC_TZ_DEFAULT_MIN */ + +#ifndef RT_LIBC_TZ_DEFAULT_SEC +#define RT_LIBC_TZ_DEFAULT_SEC (0U) +#endif /* RT_LIBC_TZ_DEFAULT_SEC */ + +static volatile int32_t _current_tz_offset_sec = \ + RT_LIBC_TZ_DEFAULT_HOUR * 3600U + RT_LIBC_TZ_DEFAULT_MIN * 60U + RT_LIBC_TZ_DEFAULT_SEC; + +/* return current timezone offset in seconds */ +void rt_tz_set(int32_t offset_sec) +{ + rt_base_t level; + level = rt_hw_interrupt_disable(); + _current_tz_offset_sec = offset_sec; + rt_hw_interrupt_enable(level); +} + +int32_t rt_tz_get(void) +{ + int32_t offset_sec; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + offset_sec = _current_tz_offset_sec; + rt_hw_interrupt_enable(level); + return offset_sec; +} + +int8_t rt_tz_is_dst(void) +{ + return 0U; /* TODO */ +} +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ + struct tm *gmtime_r(const time_t *timep, struct tm *r) { int i; @@ -158,8 +202,11 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r) r->tm_mon = i; r->tm_mday += work - __spm[i]; - - r->tm_isdst = tz_is_dst(); +#if defined(RT_LIBC_USING_LIGHT_TZ_DST) + r->tm_isdst = rt_tz_is_dst(); +#else + r->tm_isdst = 0U; +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ return r; } RTM_EXPORT(gmtime_r); @@ -174,8 +221,11 @@ RTM_EXPORT(gmtime); struct tm* localtime_r(const time_t* t, struct tm* r) { time_t local_tz; - - local_tz = *t + (time_t)tz_get() * 3600; +#if defined(RT_LIBC_USING_LIGHT_TZ_DST) + local_tz = *t + rt_tz_get(); +#else + local_tz = *t + 0U; +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ return gmtime_r(&local_tz, r); } RTM_EXPORT(localtime_r); @@ -192,7 +242,11 @@ time_t mktime(struct tm * const t) time_t timestamp; timestamp = timegm(t); - timestamp = timestamp - 3600 * (time_t)tz_get(); +#if defined(RT_LIBC_USING_LIGHT_TZ_DST) + timestamp = timestamp - rt_tz_get(); +#else + timestamp = timestamp - 0U; +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ return timestamp; } RTM_EXPORT(mktime); @@ -420,7 +474,11 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) if(tz != RT_NULL) { tz->tz_dsttime = DST_NONE; - tz->tz_minuteswest = -(tz_get() * 60); +#if defined(RT_LIBC_USING_LIGHT_TZ_DST) + tz->tz_minuteswest = -(rt_tz_get() / 60U); +#else + tz->tz_minuteswest = 0U; +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ } if (tv != RT_NULL) @@ -1126,29 +1184,3 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, } RTM_EXPORT(timer_settime); #endif /* RT_USING_POSIX_TIMER && RT_USING_KTIME */ - - -/* timezone */ -#ifndef RT_LIBC_DEFAULT_TIMEZONE -#define RT_LIBC_DEFAULT_TIMEZONE 8 -#endif - -static volatile int8_t _current_timezone = RT_LIBC_DEFAULT_TIMEZONE; - -void tz_set(int8_t tz) -{ - rt_base_t level; - level = rt_hw_interrupt_disable(); - _current_timezone = tz; - rt_hw_interrupt_enable(level); -} - -int8_t tz_get(void) -{ - return _current_timezone; -} - -int8_t tz_is_dst(void) -{ - return 0; -} diff --git a/components/libc/compilers/common/include/sys/time.h b/components/libc/compilers/common/include/sys/time.h index f1d8585383..c9968a9f29 100644 --- a/components/libc/compilers/common/include/sys/time.h +++ b/components/libc/compilers/common/include/sys/time.h @@ -28,19 +28,8 @@ extern "C" { #define CLOCKS_PER_SEC RT_TICK_PER_SECOND /* timezone */ +/* this method of representing timezones has been abandoned */ #define DST_NONE 0 /* not on dst */ -#define DST_USA 1 /* USA style dst */ -#define DST_AUST 2 /* Australian style dst */ -#define DST_WET 3 /* Western European dst */ -#define DST_MET 4 /* Middle European dst */ -#define DST_EET 5 /* Eastern European dst */ -#define DST_CAN 6 /* Canada */ -#define DST_GB 7 /* Great Britain and Eire */ -#define DST_RUM 8 /* Rumania */ -#define DST_TUR 9 /* Turkey */ -#define DST_AUSTALT 10 /* Australian style with shift in 1986 */ - -struct itimerspec; struct timezone { @@ -48,6 +37,15 @@ struct timezone int tz_dsttime; /* type of dst correction */ }; +/* lightweight timezone and daylight saving time */ +#ifdef RT_LIBC_USING_LIGHT_TZ_DST +void rt_tz_set(int32_t offset_sec); +int32_t rt_tz_get(void); +int8_t rt_tz_is_dst(void); +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ + +struct itimerspec; + #if defined(_GNU_SOURCE) && (defined(__x86_64__) || defined(__i386__)) /* linux x86 platform gcc use! */ #define _TIMEVAL_DEFINED @@ -218,11 +216,6 @@ int timer_gettime(timer_t timerid, struct itimerspec *its); int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); #endif /* RT_USING_POSIX_TIMER */ -/* timezone */ -void tz_set(int8_t tz); -int8_t tz_get(void); -int8_t tz_is_dst(void); - #ifdef __cplusplus } #endif /* __cplusplus */