Explorar el Código

[libc][timezone] implement lightweith timezone configuration

Meco Man hace 1 año
padre
commit
432c2f38fc

+ 1 - 5
components/libc/Kconfig

@@ -3,11 +3,7 @@ menu "C/C++ and POSIX layer"
 config RT_USING_EXTERNAL_LIBC
 config RT_USING_EXTERNAL_LIBC
     bool
     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/posix/Kconfig"
 source "$RTT_DIR/components/libc/cplusplus/Kconfig"
 source "$RTT_DIR/components/libc/cplusplus/Kconfig"
 
 

+ 26 - 0
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

+ 64 - 32
components/libc/compilers/common/ctime.c

@@ -22,6 +22,7 @@
  * 2023-07-03     xqyjlj       refactor posix time and timer
  * 2023-07-03     xqyjlj       refactor posix time and timer
  * 2023-07-16     Shell        update signal generation routine for lwp
  * 2023-07-16     Shell        update signal generation routine for lwp
  *                             adapt to new api and do the signal handling in thread context
  *                             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"
 #include "sys/time.h"
@@ -115,6 +116,49 @@ static rt_err_t _control_rtc(int cmd, void *arg)
 #endif /* RT_USING_RTC */
 #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)
 struct tm *gmtime_r(const time_t *timep, struct tm *r)
 {
 {
     int i;
     int i;
@@ -158,8 +202,11 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r)
 
 
     r->tm_mon = i;
     r->tm_mon = i;
     r->tm_mday += work - __spm[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;
     return r;
 }
 }
 RTM_EXPORT(gmtime_r);
 RTM_EXPORT(gmtime_r);
@@ -174,8 +221,11 @@ RTM_EXPORT(gmtime);
 struct tm* localtime_r(const time_t* t, struct tm* r)
 struct tm* localtime_r(const time_t* t, struct tm* r)
 {
 {
     time_t local_tz;
     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);
     return gmtime_r(&local_tz, r);
 }
 }
 RTM_EXPORT(localtime_r);
 RTM_EXPORT(localtime_r);
@@ -192,7 +242,11 @@ time_t mktime(struct tm * const t)
     time_t timestamp;
     time_t timestamp;
 
 
     timestamp = timegm(t);
     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;
     return timestamp;
 }
 }
 RTM_EXPORT(mktime);
 RTM_EXPORT(mktime);
@@ -420,7 +474,11 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
     if(tz != RT_NULL)
     if(tz != RT_NULL)
     {
     {
         tz->tz_dsttime = DST_NONE;
         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)
     if (tv != RT_NULL)
@@ -1126,29 +1184,3 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
 }
 }
 RTM_EXPORT(timer_settime);
 RTM_EXPORT(timer_settime);
 #endif /* RT_USING_POSIX_TIMER && RT_USING_KTIME */
 #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;
-}

+ 10 - 17
components/libc/compilers/common/include/sys/time.h

@@ -28,19 +28,8 @@ extern "C" {
 #define CLOCKS_PER_SEC RT_TICK_PER_SECOND
 #define CLOCKS_PER_SEC RT_TICK_PER_SECOND
 
 
 /* timezone */
 /* timezone */
+/* this method of representing timezones has been abandoned */
 #define DST_NONE    0   /* not on dst */
 #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
 struct timezone
 {
 {
@@ -48,6 +37,15 @@ struct timezone
     int tz_dsttime;       /* type of dst correction */
     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__))
 #if defined(_GNU_SOURCE) && (defined(__x86_64__) || defined(__i386__))
 /* linux x86 platform gcc use! */
 /* linux x86 platform gcc use! */
 #define _TIMEVAL_DEFINED
 #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);
 int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
 #endif /* RT_USING_POSIX_TIMER */
 #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
 #ifdef __cplusplus
 }
 }
 #endif /* __cplusplus */
 #endif /* __cplusplus */