blueloveTH 2 rokov pred
rodič
commit
c5858b95db

+ 12 - 0
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.

+ 1 - 1
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.
+Returns the current struct time as a `struct_time` object.

+ 36 - 0
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})"

+ 46 - 13
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<PyStructTime>(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<std::chrono::milliseconds>(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];
     }
 

+ 11 - 0
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]);