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 {
285285
286286#[ allow( clippy:: similar_names) ]
287287fn 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+ }
289296}
290297
291298impl rustix:: fs:: MetadataExt for MetadataExt {
@@ -396,3 +403,15 @@ impl rustix::fs::MetadataExt for MetadataExt {
396403 self . ctim
397404 }
398405}
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 {
3737 #[ inline]
3838 pub fn from_std ( std : time:: SystemTime ) -> Self {
3939 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+ }
4454 }
4555 } else {
4656 Self { std }
You can’t perform that action at this time.
0 commit comments