From ab5f1d49ce03e520427c7909eda16fdf5ff66ed2 Mon Sep 17 00:00:00 2001 From: zylx Date: Wed, 24 Oct 2018 11:11:17 +0800 Subject: [PATCH] [kernel][kservice] add rt_gmtime_r api --- include/rtthread.h | 1 + src/kservice.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/include/rtthread.h b/include/rtthread.h index fc5029a220..254da139ea 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -473,6 +473,7 @@ rt_int32_t rt_vsprintf(char *dest, const char *format, va_list arg_ptr); rt_int32_t rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args); rt_int32_t rt_sprintf(char *buf, const char *format, ...); rt_int32_t rt_snprintf(char *buf, rt_size_t size, const char *format, ...); +struct tm *rt_gmtime_r(const time_t *timep, struct tm *result); #if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) rt_device_t rt_console_set_device(const char *name); diff --git a/src/kservice.c b/src/kservice.c index dbc4a2fb0e..0a60fa0142 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -1177,6 +1177,61 @@ void rt_kprintf(const char *fmt, ...) RTM_EXPORT(rt_kprintf); #endif +struct tm *rt_gmtime_r(const time_t *timep, struct tm *result) +{ +#define IS_LEAP_YEAR(year) (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + + const rt_uint32_t mon_table[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + rt_uint32_t year = 1970, month = 0; + rt_uint32_t daycount = 0, second = 0, number = 0; + + second = *timep % (24 * 60 * 60); + result->tm_hour = second / 3600; + result->tm_min = (second % 3600) / 60; + result->tm_sec = (second % 3600) % 60; + + daycount = *timep / (24 * 60 * 60); + result->tm_wday = (daycount + 4) % 7; + if (daycount != 0) + { + while (daycount >= 365) + { + number = IS_LEAP_YEAR(year) ? 366 : 365; + if (daycount >= number) + { + daycount -= number; + year++; + } + else + break; + } + result->tm_year = year - 1900; + + while (daycount >= 28) + { + if (month == 1 && IS_LEAP_YEAR(year)) + { + if (daycount >= 29) + daycount -= 29; + else + break; + } + else + { + if (daycount >= mon_table[month]) + daycount -= mon_table[month]; + else + break; + } + month++; + } + result->tm_mon = month + 1; + result->tm_mday = daycount + 1; + } + return result; +} +RTM_EXPORT(rt_gmtime_r); + #ifdef RT_USING_HEAP /** * This function allocates a memory block, which address is aligned to the