提交 432c2f38 编写于 作者: mysterywolf's avatar mysterywolf

[libc][timezone] implement lightweith timezone configuration

上级 a6959a9e
......@@ -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"
......
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
......@@ -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;
}
......@@ -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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册