Skip to content

Commit

Permalink
fscript support date_time_format
Browse files Browse the repository at this point in the history
  • Loading branch information
xianjimli committed Dec 6, 2023
1 parent 6a791f4 commit e620aaa
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 9 deletions.
3 changes: 3 additions & 0 deletions docs/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# 最新动态

2023/12/06
* fscript 增加 date\_time\_format

2023/12/05
* 完善fscript部分数学函数。
* 修复上一个高亮对话框影响下一个普通窗口播放窗口动画的问题(感谢智明提供补丁)
Expand Down
35 changes: 35 additions & 0 deletions docs/fscript_date_time.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,41 @@ var dt = date_time_create();
var year = date_time_get_prop(dt, "year");
```

### 12.date\_time\_format

> 格式化日期对象为字符串。
----------------------------

> 格式规则:
* Y 代表年(完整显示)
* M 代表月(1-12)
* D 代表日(1-31)
* h 代表时(0-23)
* H 代表时(0-11)
* m 代表分(0-59)
* s 代表秒(0-59)
* YY 代表年(只显示末两位)
* MM 代表月(01-12)
* DD 代表日(01-31)
* hh 代表时(00-23)
* HH 代表时(00-11)
* mm 代表分(00-59)
* ss 代表秒(00-59)

#### 原型

```js
date_time_format(dt, format) => str
date_time_format(epoch_time, format) => str
```

#### 示例

```js
print(date_time_format(0, "Y-M-D h:m:s")); // => "1970-1-1 0:0:0"
print(date_time_format(0, "YY-MM-DD hh:mm:ss")); // => "70-01-01 00:00:00"
```

### 更多示例

```js
Expand Down
26 changes: 26 additions & 0 deletions src/fscript_ext/fscript_date_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,31 @@ static ret_t func_date_time_set(fscript_t* fscript, fscript_args_t* args, value_
return RET_OK;
}

static ret_t func_date_time_format(fscript_t* fscript, fscript_args_t* args, value_t* result) {
str_t str;
uint64_t t;
char buff[64] = {0};
date_time_t* dt = NULL;
const char* format = NULL;
FSCRIPT_FUNC_CHECK(args->size == 2, RET_BAD_PARAMS);

format = value_str(args->args + 1);
if (args->args[0].type == VALUE_TYPE_OBJECT) {
dt = get_date_time(fscript, args);
return_value_if_fail(dt != NULL, RET_BAD_PARAMS);
t = date_time_to_time(dt);
} else {
t = value_uint64(args->args);
}

str_attach(&str, buff, sizeof(buff));
tk_date_time_format(t, format, &str);

value_dup_str(result, buff);

return RET_OK;
}

static ret_t func_time_now_us(fscript_t* fscript, fscript_args_t* args, value_t* result) {
value_set_uint64(result, time_now_us());
return RET_OK;
Expand Down Expand Up @@ -140,6 +165,7 @@ FACTORY_TABLE_ENTRY("time_now_s", func_time_now_s)
FACTORY_TABLE_ENTRY("time_now", func_time_now_s)
FACTORY_TABLE_ENTRY("is_leap_year", func_year_is_leap)
FACTORY_TABLE_ENTRY("get_days_of_month", func_get_days_of_month)
FACTORY_TABLE_ENTRY("date_time_format", func_date_time_format)

/*主要给AWBLOCK使用*/
FACTORY_TABLE_ENTRY("date_time_set_prop", func_date_time_set_prop)
Expand Down
106 changes: 98 additions & 8 deletions src/tkc/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1991,14 +1991,6 @@ int tk_sscanf(const char* str, const char* format, ...) {
}
#endif /*HAS_NO_VSSCANF*/

/**
* @method tk_levelize
* 将value转换成level。
* 比如levels为"0-20;21-40;41-60;61-80;81-100",value为50,那么返回2。
* @param {const char*} levels 级别字符串。
* @param {int32_t} value 值。
* @return {int32_t} 返回level。
*/
int32_t tk_levelize(const char* levels, int32_t value) {
int32_t level = 0;
int32_t start = 0;
Expand Down Expand Up @@ -2028,3 +2020,101 @@ int32_t tk_levelize(const char* levels, int32_t value) {

return level;
}

#include "tkc/date_time.h"

uint32_t tk_count_char(const char* str, char c) {
uint32_t nr = 0;
return_value_if_fail(str != NULL, 0);

while (*str++ == c) {
nr++;
if (*str == '\0') {
break;
}
}

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];
const char* p = format;
return_value_if_fail(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_char(p, *p);

switch (*p) {
case 'Y': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.year % 100);
} else {
str_append_format(result, 32, "%d", dt.year);
}
break;
}
case 'M': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.month);
} else {
str_append_format(result, 32, "%d", dt.month);
}
break;
}
case 'D': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.day);
} else {
str_append_format(result, 32, "%d", dt.day);
}
break;
}
case 'h': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.hour);
} else {
str_append_format(result, 32, "%d", dt.hour);
}
break;
}
case 'H': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.hour % 12);
} else {
str_append_format(result, 32, "%d", dt.hour % 12);
}
break;
}
case 'm': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.minute);
} else {
str_append_format(result, 32, "%d", dt.minute);
}
break;
}
case 's': {
if (repeat == 2) {
str_append_format(result, 32, "%02d", dt.second);
} else {
str_append_format(result, 32, "%d", dt.second);
}
break;
}
default: {
str_append_with_len(result, p, repeat);
break;
}
}
p += repeat;
}

return RET_OK;
}
43 changes: 42 additions & 1 deletion src/tkc/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1062,9 +1062,50 @@ int tk_sscanf_simple(const char* str, const char* format, ...);
* @param {const char*} levels 级别字符串。
* @param {int32_t} value 值。
* @return {int32_t} 返回level。
*/
*/
int32_t tk_levelize(const char* levels, int32_t value);

/**
* @method tk_count_char
* 统计字符串中某个字符出现的次数。
* @param {const char*} str 字符串。
* @param {char} c 字符。
* @return {uint32_t} 返回字符出现的次数。
*/
uint32_t tk_count_char(const char* str, char c);

/**
* @method tk_date_time_format
* 格式化时间。
* 格式规则:
* * Y 代表年(完整显示)
* * M 代表月(1-12)
* * D 代表日(1-31)
* * h 代表时(0-23)
* * H 代表时(0-11)
* * m 代表分(0-59)
* * s 代表秒(0-59)
* * YY 代表年(只显示末两位)
* * MM 代表月(01-12)
* * DD 代表日(01-31)
* * hh 代表时(00-23)
* * HH 代表时(00-11)
* * mm 代表分(00-59)
* * ss 代表秒(00-59)
*
* 如 日期时间为:2018/11/12 9:10:20
* * "Y/M/D"显示为"2018/11/12"
* * "Y-M-D"显示为"2018-11-12"
* * "Y-M-D h:m:s"显示为"2018-11-12 9:10:20"
* * "Y-M-D hh:mm:ss"显示为"2018-11-12 09:10:20"
*
* @param {uint64_t} time 时间。
* @param {const char*} format 格式化字符串。
* @param {str_t*} result 用于返回结果。
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
ret_t tk_date_time_format(uint64_t time, const char* format, str_t* result);

#define TK_STRDUP(str) ((str) != NULL) ? tk_strdup(str) : NULL
#define TK_STRNDUP(str, len) ((str) != NULL) ? tk_strndup(str, len) : NULL

Expand Down
43 changes: 43 additions & 0 deletions tests/fscript_date_time_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "tkc/fscript.h"
#include "tkc/object_default.h"
#include "gtest/gtest.h"

TEST(FExpr, date_time_format1) {
value_t v;
tk_object_t* obj = object_default_create();

fscript_eval(obj, "date_time_format(0, \"Y\")", &v);
ASSERT_STREQ(value_str(&v), "1970");
value_reset(&v);

fscript_eval(obj, "date_time_format(0, \"Y-M-D\")", &v);
ASSERT_STREQ(value_str(&v), "1970-1-1");
value_reset(&v);

fscript_eval(obj, "date_time_format(0, \"Y-M-D h:m:s\")", &v);
ASSERT_STREQ(value_str(&v), "1970-1-1 0:0:0");
value_reset(&v);

TK_OBJECT_UNREF(obj);
}


TEST(FExpr, date_time_format2) {
value_t v;
tk_object_t* obj = object_default_create();

fscript_eval(obj, "var dt = date_time_create(); date_time_from_time(dt, 61); date_time_format(dt, \"Y\")", &v);
ASSERT_STREQ(value_str(&v), "1970");
value_reset(&v);

fscript_eval(obj, "var dt = date_time_create(); date_time_from_time(dt, 61); date_time_format(dt, \"Y-M-D\")", &v);
ASSERT_STREQ(value_str(&v), "1970-1-1");
value_reset(&v);

fscript_eval(obj, "var dt = date_time_create(); date_time_from_time(dt, 61); date_time_format(dt, \"Y-M-D h:m:s\")", &v);
ASSERT_STREQ(value_str(&v), "1970-1-1 0:1:1");
value_reset(&v);

TK_OBJECT_UNREF(obj);

}
30 changes: 30 additions & 0 deletions tests/utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1192,3 +1192,33 @@ TEST(Utils, levelize3) {
ASSERT_EQ(tk_levelize("0-20;21-40", 30), 1);
ASSERT_EQ(tk_levelize("0-20;21-40", 100), 1);
}

TEST(Utils, tk_date_time_format) {
str_t str;
char buff[128];

str_attach(&str, buff, sizeof(buff));
ASSERT_EQ(tk_date_time_format(0, "", &str), RET_OK);
ASSERT_STREQ(str.str, "");

ASSERT_EQ(tk_date_time_format(0, "Y", &str), RET_OK);
ASSERT_STREQ(str.str, "1970");

ASSERT_EQ(tk_date_time_format(0, "Y-M-D", &str), RET_OK);
ASSERT_STREQ(str.str, "1970-1-1");

ASSERT_EQ(tk_date_time_format(0, "Y-M-D h:m:s", &str), RET_OK);
ASSERT_STREQ(str.str, "1970-1-1 0:0:0");

ASSERT_EQ(tk_date_time_format(0, "YY", &str), RET_OK);
ASSERT_STREQ(str.str, "70");

ASSERT_EQ(tk_date_time_format(0, "YY-MM-DD", &str), RET_OK);
ASSERT_STREQ(str.str, "70-01-01");

ASSERT_EQ(tk_date_time_format(0, "YY-MM-DD hh:mm:ss", &str), RET_OK);
ASSERT_STREQ(str.str, "70-01-01 00:00:00");

ASSERT_EQ(tk_date_time_format(3765, "YY-MM-DD hh:mm:ss", &str), RET_OK);
ASSERT_STREQ(str.str, "70-01-01 01:02:45");
}

0 comments on commit e620aaa

Please sign in to comment.