@@ -6,9 +6,10 @@ use std::thread;
6
6
use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
7
7
8
8
use crate :: function:: { OptionalArg , PyFuncArgs } ;
9
+ use crate :: obj:: objstr:: PyStringRef ;
9
10
use crate :: obj:: objtype:: PyClassRef ;
10
11
use crate :: obj:: { objfloat, objint, objtype} ;
11
- use crate :: pyobject:: { PyClassImpl , PyObjectRef , PyResult , PyValue } ;
12
+ use crate :: pyobject:: { PyClassImpl , PyObjectRef , PyRef , PyResult , PyValue } ;
12
13
use crate :: vm:: VirtualMachine ;
13
14
14
15
use num_traits:: cast:: ToPrimitive ;
@@ -87,20 +88,78 @@ fn time_gmtime(secs: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult<
87
88
}
88
89
89
90
fn time_localtime ( secs : OptionalArg < PyObjectRef > , vm : & VirtualMachine ) -> PyResult < PyStructTime > {
91
+ let instant = optional_or_localtime ( secs, vm) ?;
92
+ let value = PyStructTime :: new ( instant) ;
93
+ Ok ( value)
94
+ }
95
+
96
+ /// Construct a localtime from the optional seconds, or get the current local time.
97
+ fn optional_or_localtime (
98
+ secs : OptionalArg < PyObjectRef > ,
99
+ vm : & VirtualMachine ,
100
+ ) -> PyResult < NaiveDateTime > {
90
101
let default = chrono:: offset:: Local :: now ( ) . naive_local ( ) ;
91
102
let instant = match secs {
92
103
OptionalArg :: Present ( secs) => pyobj_to_naive_date_time ( & secs, vm) ?. unwrap_or ( default) ,
93
104
OptionalArg :: Missing => default,
94
105
} ;
95
- let value = PyStructTime :: new ( instant) ;
96
- Ok ( value)
106
+ Ok ( instant)
107
+ }
108
+
109
+ const CFMT : & str = "%a %b %e %H:%M:%S %Y" ;
110
+
111
+ fn time_asctime ( t : OptionalArg < PyStructTimeRef > , vm : & VirtualMachine ) -> PyResult {
112
+ let default = chrono:: offset:: Local :: now ( ) . naive_local ( ) ;
113
+ let instant = match t {
114
+ OptionalArg :: Present ( t) => t. get_date_time ( ) ,
115
+ OptionalArg :: Missing => default,
116
+ } ;
117
+ let formatted_time = instant. format ( & CFMT ) . to_string ( ) ;
118
+ Ok ( vm. ctx . new_str ( formatted_time) )
119
+ }
120
+
121
+ fn time_ctime ( secs : OptionalArg < PyObjectRef > , vm : & VirtualMachine ) -> PyResult < String > {
122
+ let instant = optional_or_localtime ( secs, vm) ?;
123
+ let formatted_time = instant. format ( & CFMT ) . to_string ( ) ;
124
+ Ok ( formatted_time)
125
+ }
126
+
127
+ fn time_strftime (
128
+ format : PyStringRef ,
129
+ t : OptionalArg < PyStructTimeRef > ,
130
+ vm : & VirtualMachine ,
131
+ ) -> PyResult {
132
+ let default = chrono:: offset:: Local :: now ( ) . naive_local ( ) ;
133
+ let instant = match t {
134
+ OptionalArg :: Present ( t) => t. get_date_time ( ) ,
135
+ OptionalArg :: Missing => default,
136
+ } ;
137
+ let formatted_time = instant. format ( & format. value ) . to_string ( ) ;
138
+ Ok ( vm. ctx . new_str ( formatted_time) )
139
+ }
140
+
141
+ fn time_strptime (
142
+ string : PyStringRef ,
143
+ format : OptionalArg < PyStringRef > ,
144
+ vm : & VirtualMachine ,
145
+ ) -> PyResult < PyStructTime > {
146
+ let format: String = match format {
147
+ OptionalArg :: Present ( format) => format. value . clone ( ) ,
148
+ OptionalArg :: Missing => "%a %b %H:%M:%S %Y" . to_string ( ) ,
149
+ } ;
150
+ let instant = NaiveDateTime :: parse_from_str ( & string. value , & format)
151
+ . map_err ( |e| vm. new_value_error ( format ! ( "Parse error: {:?}" , e) ) ) ?;
152
+ let struct_time = PyStructTime :: new ( instant) ;
153
+ Ok ( struct_time)
97
154
}
98
155
99
156
#[ pyclass( name = "struct_time" ) ]
100
157
struct PyStructTime {
101
158
tm : NaiveDateTime ,
102
159
}
103
160
161
+ type PyStructTimeRef = PyRef < PyStructTime > ;
162
+
104
163
impl fmt:: Debug for PyStructTime {
105
164
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
106
165
write ! ( f, "struct_time()" )
@@ -130,6 +189,10 @@ impl PyStructTime {
130
189
)
131
190
}
132
191
192
+ fn get_date_time ( & self ) -> NaiveDateTime {
193
+ self . tm
194
+ }
195
+
133
196
#[ pyproperty( name = "tm_year" ) ]
134
197
fn tm_year ( & self , _vm : & VirtualMachine ) -> i32 {
135
198
self . tm . date ( ) . year ( )
@@ -172,9 +235,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
172
235
let struct_time_type = PyStructTime :: make_class ( ctx) ;
173
236
174
237
py_module ! ( vm, "time" , {
238
+ "asctime" => ctx. new_rustfunc( time_asctime) ,
239
+ "ctime" => ctx. new_rustfunc( time_ctime) ,
175
240
"gmtime" => ctx. new_rustfunc( time_gmtime) ,
176
241
"localtime" => ctx. new_rustfunc( time_localtime) ,
177
242
"monotonic" => ctx. new_rustfunc( time_monotonic) ,
243
+ "strftime" => ctx. new_rustfunc( time_strftime) ,
244
+ "strptime" => ctx. new_rustfunc( time_strptime) ,
178
245
"sleep" => ctx. new_rustfunc( time_sleep) ,
179
246
"struct_time" => struct_time_type,
180
247
"time" => ctx. new_rustfunc( time_time)
0 commit comments