@@ -6,9 +6,10 @@ use std::thread;
66use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
77
88use crate :: function:: { OptionalArg , PyFuncArgs } ;
9+ use crate :: obj:: objstr:: PyStringRef ;
910use crate :: obj:: objtype:: PyClassRef ;
1011use crate :: obj:: { objfloat, objint, objtype} ;
11- use crate :: pyobject:: { PyClassImpl , PyObjectRef , PyResult , PyValue } ;
12+ use crate :: pyobject:: { PyClassImpl , PyObjectRef , PyRef , PyResult , PyValue } ;
1213use crate :: vm:: VirtualMachine ;
1314
1415use num_traits:: cast:: ToPrimitive ;
@@ -87,20 +88,78 @@ fn time_gmtime(secs: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult<
8788}
8889
8990fn 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 > {
90101 let default = chrono:: offset:: Local :: now ( ) . naive_local ( ) ;
91102 let instant = match secs {
92103 OptionalArg :: Present ( secs) => pyobj_to_naive_date_time ( & secs, vm) ?. unwrap_or ( default) ,
93104 OptionalArg :: Missing => default,
94105 } ;
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)
97154}
98155
99156#[ pyclass( name = "struct_time" ) ]
100157struct PyStructTime {
101158 tm : NaiveDateTime ,
102159}
103160
161+ type PyStructTimeRef = PyRef < PyStructTime > ;
162+
104163impl fmt:: Debug for PyStructTime {
105164 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
106165 write ! ( f, "struct_time()" )
@@ -130,6 +189,10 @@ impl PyStructTime {
130189 )
131190 }
132191
192+ fn get_date_time ( & self ) -> NaiveDateTime {
193+ self . tm
194+ }
195+
133196 #[ pyproperty( name = "tm_year" ) ]
134197 fn tm_year ( & self , _vm : & VirtualMachine ) -> i32 {
135198 self . tm . date ( ) . year ( )
@@ -172,9 +235,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
172235 let struct_time_type = PyStructTime :: make_class ( ctx) ;
173236
174237 py_module ! ( vm, "time" , {
238+ "asctime" => ctx. new_rustfunc( time_asctime) ,
239+ "ctime" => ctx. new_rustfunc( time_ctime) ,
175240 "gmtime" => ctx. new_rustfunc( time_gmtime) ,
176241 "localtime" => ctx. new_rustfunc( time_localtime) ,
177242 "monotonic" => ctx. new_rustfunc( time_monotonic) ,
243+ "strftime" => ctx. new_rustfunc( time_strftime) ,
244+ "strptime" => ctx. new_rustfunc( time_strptime) ,
178245 "sleep" => ctx. new_rustfunc( time_sleep) ,
179246 "struct_time" => struct_time_type,
180247 "time" => ctx. new_rustfunc( time_time)
0 commit comments