@@ -7,7 +7,7 @@ use serde_json::Value as Json;
7
7
use std:: str:: from_utf8;
8
8
9
9
#[ cfg( feature = "with-chrono" ) ]
10
- use chrono:: { DateTime , FixedOffset , NaiveDate , NaiveDateTime , NaiveTime , Utc } ;
10
+ use chrono:: { DateTime , FixedOffset , Local , NaiveDate , NaiveDateTime , NaiveTime , Utc } ;
11
11
12
12
#[ cfg( feature = "with-rust_decimal" ) ]
13
13
use rust_decimal:: Decimal ;
@@ -61,6 +61,10 @@ pub enum Value {
61
61
#[ cfg_attr( docsrs, doc( cfg( feature = "with-chrono" ) ) ) ]
62
62
DateTimeUtc ( Option < Box < DateTime < Utc > > > ) ,
63
63
64
+ #[ cfg( feature = "with-chrono" ) ]
65
+ #[ cfg_attr( docsrs, doc( cfg( feature = "with-chrono" ) ) ) ]
66
+ DateTimeLocal ( Option < Box < DateTime < Local > > > ) ,
67
+
64
68
#[ cfg( feature = "with-chrono" ) ]
65
69
#[ cfg_attr( docsrs, doc( cfg( feature = "with-chrono" ) ) ) ]
66
70
DateTimeWithTimeZone ( Option < Box < DateTime < FixedOffset > > > ) ,
@@ -290,7 +294,7 @@ mod with_json {
290
294
#[ cfg_attr( docsrs, doc( cfg( feature = "with-chrono" ) ) ) ]
291
295
mod with_chrono {
292
296
use super :: * ;
293
- use chrono:: { Offset , Utc } ;
297
+ use chrono:: { Local , Offset , Utc } ;
294
298
295
299
type_to_box_value ! ( NaiveDate , Date , Date ) ;
296
300
type_to_box_value ! ( NaiveTime , Time , Time ( None ) ) ;
@@ -302,6 +306,12 @@ mod with_chrono {
302
306
}
303
307
}
304
308
309
+ impl From < DateTime < Local > > for Value {
310
+ fn from ( v : DateTime < Local > ) -> Value {
311
+ Value :: DateTimeLocal ( Some ( Box :: new ( v) ) )
312
+ }
313
+ }
314
+
305
315
impl From < DateTime < FixedOffset > > for Value {
306
316
fn from ( x : DateTime < FixedOffset > ) -> Value {
307
317
let v = DateTime :: < FixedOffset > :: from_utc ( x. naive_utc ( ) , x. offset ( ) . fix ( ) ) ;
@@ -332,6 +342,29 @@ mod with_chrono {
332
342
}
333
343
}
334
344
345
+ impl Nullable for DateTime < Local > {
346
+ fn null ( ) -> Value {
347
+ Value :: DateTimeLocal ( None )
348
+ }
349
+ }
350
+
351
+ impl ValueType for DateTime < Local > {
352
+ fn try_from ( v : Value ) -> Result < Self , ValueTypeErr > {
353
+ match v {
354
+ Value :: DateTimeLocal ( Some ( x) ) => Ok ( * x) ,
355
+ _ => Err ( ValueTypeErr ) ,
356
+ }
357
+ }
358
+
359
+ fn type_name ( ) -> String {
360
+ stringify ! ( DateTime <Local >) . to_owned ( )
361
+ }
362
+
363
+ fn column_type ( ) -> ColumnType {
364
+ ColumnType :: TimestampWithTimeZone ( None )
365
+ }
366
+ }
367
+
335
368
impl Nullable for DateTime < FixedOffset > {
336
369
fn null ( ) -> Value {
337
370
Value :: DateTimeWithTimeZone ( None )
@@ -563,6 +596,13 @@ impl Value {
563
596
#[ cfg( not( feature = "with-chrono" ) ) ]
564
597
return false ;
565
598
}
599
+
600
+ pub fn is_date_time_local ( & self ) -> bool {
601
+ #[ cfg( feature = "with-chrono" ) ]
602
+ return matches ! ( self , Self :: DateTimeLocal ( _) ) ;
603
+ #[ cfg( not( feature = "with-chrono" ) ) ]
604
+ return false ;
605
+ }
566
606
pub fn is_date_time_with_time_zone ( & self ) -> bool {
567
607
#[ cfg( feature = "with-chrono" ) ]
568
608
return matches ! ( self , Self :: DateTimeWithTimeZone ( _) ) ;
@@ -582,6 +622,18 @@ impl Value {
582
622
panic ! ( "not Value::DateTimeUtc" )
583
623
}
584
624
625
+ #[ cfg( feature = "with-chrono" ) ]
626
+ pub fn as_ref_date_time_local ( & self ) -> Option < & DateTime < Local > > {
627
+ match self {
628
+ Self :: DateTimeLocal ( v) => box_to_opt_ref ! ( v) ,
629
+ _ => panic ! ( "not Value::DateTimeLocal" ) ,
630
+ }
631
+ }
632
+ #[ cfg( not( feature = "with-chrono" ) ) ]
633
+ pub fn as_ref_date_time_local ( & self ) -> Option < & bool > {
634
+ panic ! ( "not Value::DateTimeLocal" )
635
+ }
636
+
585
637
#[ cfg( feature = "with-chrono" ) ]
586
638
pub fn as_ref_date_time_with_time_zone ( & self ) -> Option < & DateTime < FixedOffset > > {
587
639
match self {
@@ -599,6 +651,7 @@ impl Value {
599
651
match self {
600
652
Self :: DateTime ( v) => v. as_ref ( ) . map ( |v| v. to_string ( ) ) ,
601
653
Self :: DateTimeUtc ( v) => v. as_ref ( ) . map ( |v| v. naive_utc ( ) . to_string ( ) ) ,
654
+ Self :: DateTimeLocal ( v) => v. as_ref ( ) . map ( |v| v. naive_utc ( ) . to_string ( ) ) ,
602
655
Self :: DateTimeWithTimeZone ( v) => v. as_ref ( ) . map ( |v| v. naive_utc ( ) . to_string ( ) ) ,
603
656
_ => panic ! ( "not Value::DateTime" ) ,
604
657
}
@@ -1024,6 +1077,8 @@ pub fn sea_value_to_json_value(value: &Value) -> Json {
1024
1077
Value :: DateTimeWithTimeZone ( _) => CommonSqlQueryBuilder . value_to_string ( value) . into ( ) ,
1025
1078
#[ cfg( feature = "with-chrono" ) ]
1026
1079
Value :: DateTimeUtc ( _) => CommonSqlQueryBuilder . value_to_string ( value) . into ( ) ,
1080
+ #[ cfg( feature = "with-chrono" ) ]
1081
+ Value :: DateTimeLocal ( _) => CommonSqlQueryBuilder . value_to_string ( value) . into ( ) ,
1027
1082
#[ cfg( feature = "with-rust_decimal" ) ]
1028
1083
Value :: Decimal ( Some ( v) ) => {
1029
1084
use rust_decimal:: prelude:: ToPrimitive ;
@@ -1330,6 +1385,17 @@ mod tests {
1330
1385
assert_eq ! ( out, timestamp) ;
1331
1386
}
1332
1387
1388
+ #[ test]
1389
+ #[ cfg( feature = "with-chrono" ) ]
1390
+ fn test_chrono_local_value ( ) {
1391
+ let timestamp_utc =
1392
+ DateTime :: < Utc > :: from_utc ( NaiveDate :: from_ymd ( 2022 , 1 , 2 ) . and_hms ( 3 , 4 , 5 ) , Utc ) ;
1393
+ let timestamp_local: DateTime < Local > = timestamp_utc. into ( ) ;
1394
+ let value: Value = timestamp_local. into ( ) ;
1395
+ let out: DateTime < Local > = value. unwrap ( ) ;
1396
+ assert_eq ! ( out, timestamp_local) ;
1397
+ }
1398
+
1333
1399
#[ test]
1334
1400
#[ cfg( feature = "with-chrono" ) ]
1335
1401
fn test_chrono_timezone_value ( ) {
0 commit comments