From c5858b95db26b63813775eeef649c71b2fd06371 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 6 Sep 2023 23:44:18 +0800 Subject: [PATCH] ... --- docs/modules/datetime.md | 12 ++++++++ docs/modules/time.md | 2 +- python/datetime.py | 36 ++++++++++++++++++++++++ src/pocketpy.cpp | 59 +++++++++++++++++++++++++++++++--------- tests/99_builtin_func.py | 11 ++++++++ 5 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 docs/modules/datetime.md create mode 100644 python/datetime.py diff --git a/docs/modules/datetime.md b/docs/modules/datetime.md new file mode 100644 index 00000000..fbe13cf4 --- /dev/null +++ b/docs/modules/datetime.md @@ -0,0 +1,12 @@ +--- +icon: package +label: datetime +--- + +### `datetime.now()` + +Returns the current date and time as a `datetime` object. + +### `date.today()` + +Returns the current local date as a `date` object. \ No newline at end of file diff --git a/docs/modules/time.md b/docs/modules/time.md index 6caf0649..250b54f7 100644 --- a/docs/modules/time.md +++ b/docs/modules/time.md @@ -13,4 +13,4 @@ Suspend execution of the calling thread for the given number of seconds. ### `time.localtime()` -Returns the current struct time as a `dict` object. \ No newline at end of file +Returns the current struct time as a `struct_time` object. \ No newline at end of file diff --git a/python/datetime.py b/python/datetime.py new file mode 100644 index 00000000..01ee544c --- /dev/null +++ b/python/datetime.py @@ -0,0 +1,36 @@ +from time import localtime + +class date: + def __init__(self, year: int, month: int, day: int): + self.year = year + self.month = month + self.day = day + + @staticmethod + def today(): + t = localtime() + return date(t.tm_year, t.tm_mon, t.tm_mday) + + def __str__(self): + return f"{self.year}-{self.month}-{self.day}" + + def __repr__(self): + return f"datetime.date({self.year}, {self.month}, {self.day})" + +class datetime(date): + def __init__(self, year: int, month: int, day: int, hour: int, minute: int, second: int): + super(datetime, self).__init__(year, month, day) + self.hour = hour + self.minute = minute + self.second = second + + @staticmethod + def now(): + t = localtime() + return datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec) + + def __str__(self): + return f"{self.year}-{self.month}-{self.day} {self.hour}:{self.minute}:{self.second}" + + def __repr__(self): + return f"datetime.datetime({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})" \ No newline at end of file diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 363dda2b..d3870a6f 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1297,8 +1297,52 @@ void add_module_timeit(VM* vm){ }); } +struct PyStructTime{ + PY_CLASS(PyStructTime, time, struct_time) + + int tm_year; + int tm_mon; + int tm_mday; + int tm_hour; + int tm_min; + int tm_sec; + int tm_wday; + int tm_yday; + int tm_isdst; + + PyStructTime(std::time_t t){ + std::tm* tm = std::localtime(&t); + tm_year = tm->tm_year + 1900; + tm_mon = tm->tm_mon + 1; + tm_mday = tm->tm_mday; + tm_hour = tm->tm_hour; + tm_min = tm->tm_min; + tm_sec = tm->tm_sec + 1; + tm_wday = (tm->tm_wday + 6) % 7; + tm_yday = tm->tm_yday + 1; + tm_isdst = tm->tm_isdst; + } + + PyStructTime& _() { return *this; } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->bind_notimplemented_constructor(type); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_year", _, tm_year); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_mon", _, tm_mon); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_mday", _, tm_mday); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_hour", _, tm_hour); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_min", _, tm_min); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_sec", _, tm_sec); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_wday", _, tm_wday); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_yday", _, tm_yday); + PK_REGISTER_READONLY_FIELD(PyStructTime, "tm_isdst", _, tm_isdst); + } +}; + void add_module_time(VM* vm){ PyObject* mod = vm->new_module("time"); + PyStructTime::register_class(vm, mod); + vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) { auto now = std::chrono::system_clock::now(); return VAR(std::chrono::duration_cast(now.time_since_epoch()).count() / 1000.0); @@ -1318,18 +1362,7 @@ void add_module_time(VM* vm){ vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) { auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); - std::tm* tm = std::localtime(&t); - Dict d(vm); - d.set(VAR("tm_year"), VAR(tm->tm_year + 1900)); - d.set(VAR("tm_mon"), VAR(tm->tm_mon + 1)); - d.set(VAR("tm_mday"), VAR(tm->tm_mday)); - d.set(VAR("tm_hour"), VAR(tm->tm_hour)); - d.set(VAR("tm_min"), VAR(tm->tm_min)); - d.set(VAR("tm_sec"), VAR(tm->tm_sec + 1)); - d.set(VAR("tm_wday"), VAR((tm->tm_wday + 6) % 7)); - d.set(VAR("tm_yday"), VAR(tm->tm_yday + 1)); - d.set(VAR("tm_isdst"), VAR(tm->tm_isdst)); - return VAR(std::move(d)); + return VAR_T(PyStructTime, t); }); } @@ -1548,7 +1581,7 @@ void VM::post_init(){ add_module_base64(this); add_module_timeit(this); - for(const char* name: {"this", "functools", "collections", "heapq", "bisect", "pickle", "_long", "colorsys", "typing"}){ + for(const char* name: {"this", "functools", "collections", "heapq", "bisect", "pickle", "_long", "colorsys", "typing", "datetime"}){ _lazy_modules[name] = kPythonLibs[name]; } diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index 210c0b4f..ada8b8cc 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -1074,6 +1074,17 @@ import time # test time.time assert type(time.time()) is float +local_t = time.localtime() +assert type(local_t.tm_year) is int +assert type(local_t.tm_mon) is int +assert type(local_t.tm_mday) is int +assert type(local_t.tm_hour) is int +assert type(local_t.tm_min) is int +assert type(local_t.tm_sec) is int +assert type(local_t.tm_wday) is int +assert type(local_t.tm_yday) is int +assert type(local_t.tm_isdst) is int + # 未完全测试准确性----------------------------------------------- # 116: 1267: vm->bind_func<1>(mod, "sleep", [](VM* vm, ArgsView args) { # #####: 1268: f64 seconds = CAST_F(args[0]);