File tree Expand file tree Collapse file tree 2 files changed +34
-5
lines changed Expand file tree Collapse file tree 2 files changed +34
-5
lines changed Original file line number Diff line number Diff line change @@ -285,7 +285,14 @@ impl MetadataExt {
285
285
286
286
#[ allow( clippy:: similar_names) ]
287
287
fn system_time_from_rustix ( sec : i64 , nsec : u64 ) -> Option < SystemTime > {
288
- SystemClock :: UNIX_EPOCH . checked_add ( Duration :: new ( u64:: try_from ( sec) . unwrap ( ) , nsec as _ ) )
288
+ if sec >= 0 {
289
+ SystemClock :: UNIX_EPOCH . checked_add ( Duration :: new ( u64:: try_from ( sec) . unwrap ( ) , nsec as _ ) )
290
+ } else {
291
+ SystemClock :: UNIX_EPOCH
292
+ . checked_sub ( Duration :: new ( u64:: try_from ( -sec) . unwrap ( ) , 0 ) )
293
+ . map ( |t| t. checked_add ( Duration :: new ( 0 , nsec as u32 ) ) )
294
+ . flatten ( )
295
+ }
289
296
}
290
297
291
298
impl rustix:: fs:: MetadataExt for MetadataExt {
@@ -396,3 +403,15 @@ impl rustix::fs::MetadataExt for MetadataExt {
396
403
self . ctim
397
404
}
398
405
}
406
+
407
+ /// It should be possible to represent times before the Epoch.
408
+ /// https://github.com/bytecodealliance/cap-std/issues/328
409
+ #[ test]
410
+ fn negative_time ( ) {
411
+ let system_time = system_time_from_rustix ( -1 , 1 ) . unwrap ( ) ;
412
+ let d = SystemClock :: UNIX_EPOCH . duration_since ( system_time) . unwrap ( ) ;
413
+ assert_eq ! ( d. as_secs( ) , 0 ) ;
414
+ if !cfg ! ( emulate_second_only_system) {
415
+ assert_eq ! ( d. subsec_nanos( ) , 999999999 ) ;
416
+ }
417
+ }
Original file line number Diff line number Diff line change @@ -37,10 +37,20 @@ impl SystemTime {
37
37
#[ inline]
38
38
pub fn from_std ( std : time:: SystemTime ) -> Self {
39
39
if cfg ! ( emulate_second_only_system) {
40
- let duration = std. duration_since ( time:: SystemTime :: UNIX_EPOCH ) . unwrap ( ) ;
41
- let secs = time:: Duration :: from_secs ( duration. as_secs ( ) ) ;
42
- Self {
43
- std : time:: SystemTime :: UNIX_EPOCH . checked_add ( secs) . unwrap ( ) ,
40
+ match std. duration_since ( time:: SystemTime :: UNIX_EPOCH ) {
41
+ Ok ( duration) => {
42
+ let secs = time:: Duration :: from_secs ( duration. as_secs ( ) ) ;
43
+ Self {
44
+ std : time:: SystemTime :: UNIX_EPOCH . checked_add ( secs) . unwrap ( ) ,
45
+ }
46
+ }
47
+ Err ( _) => {
48
+ let duration = time:: SystemTime :: UNIX_EPOCH . duration_since ( std) . unwrap ( ) ;
49
+ let secs = time:: Duration :: from_secs ( duration. as_secs ( ) ) ;
50
+ Self {
51
+ std : time:: SystemTime :: UNIX_EPOCH . checked_sub ( secs) . unwrap ( ) ,
52
+ }
53
+ }
44
54
}
45
55
} else {
46
56
Self { std }
You can’t perform that action at this time.
0 commit comments