mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-09 03:51:08 +08:00
improve date_time format
This commit is contained in:
parent
127f5b70b5
commit
cabaf1575d
@ -1,5 +1,9 @@
|
||||
# 最新动态
|
||||
|
||||
2024/10/11
|
||||
* 统一date_time_format处理(感谢兆坤提供补丁)
|
||||
|
||||
|
||||
2024/10/10
|
||||
* 完善object compare(感谢朝泽提供补丁)
|
||||
* 修复拼写错误(感谢兆坤提供补丁)
|
||||
|
@ -19,152 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/utf8.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "base/locale_info.h"
|
||||
#include "base/date_time_format.h"
|
||||
|
||||
static uint32_t count_char(const wchar_t* p, wchar_t c) {
|
||||
uint32_t nr = 0;
|
||||
static ret_t date_time_format_translate_callback(void* ctx, const void* data) {
|
||||
const char** dst = (const char**)(ctx);
|
||||
const char* src = (const char*)(data);
|
||||
return_value_if_fail(dst != NULL && src != NULL, RET_BAD_PARAMS);
|
||||
|
||||
while (*p++ == c) {
|
||||
nr++;
|
||||
}
|
||||
*dst = locale_info_tr(locale_info(), src);
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
static wchar_t* translate_wday(wchar_t* str, uint32_t size, uint32_t wday) {
|
||||
return_value_if_fail(wday < 7, NULL);
|
||||
|
||||
static const char* const wdays[] = {
|
||||
"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat",
|
||||
};
|
||||
|
||||
const char* utf8 = locale_info_tr(locale_info(), wdays[wday]);
|
||||
return tk_utf8_to_utf16(utf8, str, size);
|
||||
}
|
||||
|
||||
static wchar_t* translate_meridiem(wchar_t* str, uint32_t size, uint32_t hour) {
|
||||
const char* utf8 = locale_info_tr(locale_info(), hour < 12 ? "AM" : "PM");
|
||||
return tk_utf8_to_utf16(utf8, str, size);
|
||||
}
|
||||
|
||||
static wchar_t* translate_month(wchar_t* str, uint32_t size, uint32_t month) {
|
||||
return_value_if_fail(month < 13 && month > 0, NULL);
|
||||
|
||||
static const char* const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sept", "Oct", "Nov", "Dec"};
|
||||
|
||||
const char* utf8 = locale_info_tr(locale_info(), months[month - 1]);
|
||||
return tk_utf8_to_utf16(utf8, str, size);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t wstr_format_date_time(wstr_t* str, const char* format, const date_time_t* dt) {
|
||||
wchar_t temp[32];
|
||||
return_value_if_fail(format != NULL && str != NULL, RET_BAD_PARAMS);
|
||||
ret_t ret = RET_OK;
|
||||
str_t result;
|
||||
return_value_if_fail(str != NULL && format != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wstr_t wformat;
|
||||
wstr_init(&wformat, strlen(format) + 2);
|
||||
wstr_set_utf8(&wformat, format);
|
||||
const wchar_t* p = wformat.str;
|
||||
str_init(&result, tk_strlen(format));
|
||||
|
||||
str->size = 0;
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
while (*p) {
|
||||
int32_t repeat = count_char(p, *p);
|
||||
|
||||
switch (*p) {
|
||||
case 'Y': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", (dt->year % 100));
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->year);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'M': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", dt->month);
|
||||
} else if (repeat == 3) {
|
||||
translate_month(temp, ARRAY_SIZE(temp), dt->month);
|
||||
wstr_append(str, temp);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->month);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'D': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", dt->day);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->day);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", dt->hour);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->hour);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'T': {
|
||||
translate_meridiem(temp, ARRAY_SIZE(temp), dt->hour);
|
||||
wstr_append(str, temp);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
if (repeat == 2) {
|
||||
if (dt->hour == 0) {
|
||||
wstr_push_int(str, "%02d", 12);
|
||||
} else {
|
||||
wstr_push_int(str, "%02d", ((dt->hour > 12) ? (dt->hour - 12) : (dt->hour)));
|
||||
}
|
||||
} else {
|
||||
if (dt->hour == 0) {
|
||||
wstr_push_int(str, "%d", 12);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", ((dt->hour > 12) ? (dt->hour - 12) : (dt->hour)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", dt->minute);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->minute);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
if (repeat == 2) {
|
||||
wstr_push_int(str, "%02d", dt->second);
|
||||
} else {
|
||||
wstr_push_int(str, "%d", dt->second);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w': {
|
||||
wstr_push_int(str, "%d", dt->wday);
|
||||
break;
|
||||
}
|
||||
case 'W': {
|
||||
translate_wday(temp, ARRAY_SIZE(temp), dt->wday);
|
||||
wstr_append(str, temp);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
wstr_append_with_len(str, p, repeat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
p += repeat;
|
||||
ret = tk_date_time_format_impl(dt, format, &result, date_time_format_translate_callback);
|
||||
if (RET_OK == ret) {
|
||||
ret = wstr_set_utf8_with_len(str, result.str, result.size);
|
||||
}
|
||||
wstr_reset(&wformat);
|
||||
|
||||
return RET_OK;
|
||||
str_reset(&result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t wstr_format_time(wstr_t* str, const char* format, uint64_t time) {
|
||||
|
@ -22,7 +22,6 @@
|
||||
#ifndef TK_DATE_TIME_FORMAT_H
|
||||
#define TK_DATE_TIME_FORMAT_H
|
||||
|
||||
#include "tkc/str.h"
|
||||
#include "tkc/wstr.h"
|
||||
#include "tkc/types_def.h"
|
||||
#include "tkc/date_time.h"
|
||||
|
@ -2136,8 +2136,6 @@ int32_t tk_levelize(const char* levels, int32_t value) {
|
||||
return level;
|
||||
}
|
||||
|
||||
#include "tkc/date_time.h"
|
||||
|
||||
static uint32_t tk_count_repeat_char(const char* str, char c) {
|
||||
uint32_t nr = 0;
|
||||
return_value_if_fail(str != NULL, 0);
|
||||
@ -2152,16 +2150,12 @@ static uint32_t tk_count_repeat_char(const char* str, char c) {
|
||||
return nr;
|
||||
}
|
||||
|
||||
ret_t tk_date_time_format(uint64_t time, const char* format, str_t* result) {
|
||||
date_time_t dt;
|
||||
wchar_t temp[32];
|
||||
ret_t tk_date_time_format_impl(const date_time_t* dt, const char* format, str_t* result,
|
||||
tk_on_result_t translate_callback) {
|
||||
const char* p = format;
|
||||
return_value_if_fail(format != NULL && result != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(dt != NULL && format != NULL && result != NULL, RET_BAD_PARAMS);
|
||||
|
||||
str_clear(result);
|
||||
date_time_init(&dt);
|
||||
date_time_from_time(&dt, time);
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
|
||||
while (*p) {
|
||||
int32_t repeat = tk_count_repeat_char(p, *p);
|
||||
@ -2169,65 +2163,101 @@ ret_t tk_date_time_format(uint64_t time, const char* format, str_t* result) {
|
||||
switch (*p) {
|
||||
case 'Y': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.year % 100);
|
||||
str_append_format(result, 32, "%02d", dt->year % 100);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.year);
|
||||
str_append_format(result, 32, "%d", dt->year);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'M': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.month);
|
||||
str_append_format(result, 32, "%02d", dt->month);
|
||||
} else if (repeat == 3) {
|
||||
static const char* const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sept", "Oct", "Nov", "Dec"};
|
||||
if (dt->month - 1 < ARRAY_SIZE(months)) {
|
||||
const char* tr_str = months[dt->month - 1];
|
||||
if (translate_callback != NULL) {
|
||||
translate_callback(&tr_str, months[dt->month - 1]);
|
||||
}
|
||||
str_append(result, tr_str);
|
||||
}
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.month);
|
||||
str_append_format(result, 32, "%d", dt->month);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'D': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.day);
|
||||
str_append_format(result, 32, "%02d", dt->day);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.day);
|
||||
str_append_format(result, 32, "%d", dt->day);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.hour);
|
||||
str_append_format(result, 32, "%02d", dt->hour);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.hour);
|
||||
str_append_format(result, 32, "%d", dt->hour);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'T': {
|
||||
const char* str = (dt->hour < 12) ? "AM" : "PM";
|
||||
const char* tr_str = str;
|
||||
if (translate_callback != NULL) {
|
||||
translate_callback(&tr_str, str);
|
||||
}
|
||||
str_append(result, tr_str);
|
||||
break;
|
||||
}
|
||||
case 'H': {
|
||||
if (repeat == 2) {
|
||||
if (dt.hour == 0) {
|
||||
if (dt->hour == 0) {
|
||||
str_append_format(result, 32, "%02d", 12);
|
||||
} else {
|
||||
str_append_format(result, 32, "%02d", ((dt.hour > 12) ? (dt.hour - 12) : (dt.hour)));
|
||||
str_append_format(result, 32, "%02d", ((dt->hour > 12) ? (dt->hour - 12) : (dt->hour)));
|
||||
}
|
||||
} else {
|
||||
if (dt.hour == 0) {
|
||||
if (dt->hour == 0) {
|
||||
str_append_format(result, 32, "%d", 12);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", ((dt.hour > 12) ? (dt.hour - 12) : (dt.hour)));
|
||||
str_append_format(result, 32, "%d", ((dt->hour > 12) ? (dt->hour - 12) : (dt->hour)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.minute);
|
||||
str_append_format(result, 32, "%02d", dt->minute);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.minute);
|
||||
str_append_format(result, 32, "%d", dt->minute);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
if (repeat == 2) {
|
||||
str_append_format(result, 32, "%02d", dt.second);
|
||||
str_append_format(result, 32, "%02d", dt->second);
|
||||
} else {
|
||||
str_append_format(result, 32, "%d", dt.second);
|
||||
str_append_format(result, 32, "%d", dt->second);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w': {
|
||||
str_append_format(result, 32, "%d", dt->wday);
|
||||
break;
|
||||
}
|
||||
case 'W': {
|
||||
static const char* const wdays[] = {
|
||||
"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat",
|
||||
};
|
||||
if (dt->wday < ARRAY_SIZE(wdays)) {
|
||||
const char* tr_str = wdays[dt->wday];
|
||||
if (translate_callback != NULL) {
|
||||
translate_callback(&tr_str, wdays[dt->wday]);
|
||||
}
|
||||
str_append(result, tr_str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2242,6 +2272,16 @@ ret_t tk_date_time_format(uint64_t time, const char* format, str_t* result) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t tk_date_time_format(uint64_t time, const char* format, str_t* result) {
|
||||
date_time_t dt;
|
||||
return_value_if_fail(format != NULL && result != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(&dt, 0x00, sizeof(dt));
|
||||
date_time_from_time(&dt, time);
|
||||
|
||||
return tk_date_time_format_impl(&dt, format, result, NULL);
|
||||
}
|
||||
|
||||
uint32_t tk_bits_to_bytes(uint32_t bits) {
|
||||
return (bits + 7) / 8;
|
||||
}
|
||||
|
@ -1162,6 +1162,9 @@ uint32_t tk_count_char(const char* str, char c);
|
||||
* * H 代表时(1-12)
|
||||
* * m 代表分(0-59)
|
||||
* * s 代表秒(0-59)
|
||||
* * w 代表星期(0-6)
|
||||
* * W 代表星期的英文缩写
|
||||
* * T 代表时段AM/PM
|
||||
* * YY 代表年(只显示末两位)
|
||||
* * MM 代表月(01-12)
|
||||
* * DD 代表日(01-31)
|
||||
@ -1169,6 +1172,7 @@ uint32_t tk_count_char(const char* str, char c);
|
||||
* * HH 代表时(01-12)
|
||||
* * mm 代表分(00-59)
|
||||
* * ss 代表秒(00-59)
|
||||
* * MMM 代表月的英文缩写
|
||||
*
|
||||
* 如 日期时间为:2018/11/12 9:10:20
|
||||
* * "Y/M/D"显示为"2018/11/12"
|
||||
@ -1358,6 +1362,11 @@ ret_t tk_mergesort(void* base, size_t nmemb, size_t size, tk_compare_t cmp);
|
||||
/*public for test*/
|
||||
ret_t xml_file_expand(const char* filename, str_t* s, const char* data);
|
||||
|
||||
/* private */
|
||||
#include "tkc/date_time.h"
|
||||
ret_t tk_date_time_format_impl(const date_time_t* dt, const char* format, str_t* result,
|
||||
tk_on_result_t translate_callback);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_UTILS_H*/
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "tkc/str.h"
|
||||
#include "base/date_time_format.h"
|
||||
|
||||
TEST(DateTimeFormat, basic) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user