@@ -10,7 +10,7 @@ use jiff::fmt::strtime;
1010use jiff:: tz:: TimeZone ;
1111use jiff:: { Timestamp , Zoned } ;
1212#[ cfg( all( unix, not( target_os = "macos" ) , not( target_os = "redox" ) ) ) ]
13- use libc:: { CLOCK_REALTIME , clock_settime, timespec} ;
13+ use libc:: { clock_settime, timespec, CLOCK_REALTIME } ;
1414use std:: fs:: File ;
1515use std:: io:: { BufRead , BufReader } ;
1616use std:: path:: PathBuf ;
@@ -65,6 +65,7 @@ enum Format {
6565enum DateSource {
6666 Now ,
6767 File ( PathBuf ) ,
68+ FileMtime ( PathBuf ) ,
6869 Stdin ,
6970 Human ( String ) ,
7071}
@@ -146,6 +147,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
146147 "-" => DateSource :: Stdin ,
147148 _ => DateSource :: File ( file. into ( ) ) ,
148149 }
150+ } else if let Some ( file) = matches. get_one :: < String > ( OPT_REFERENCE ) {
151+ DateSource :: FileMtime ( file. into ( ) )
149152 } else {
150153 DateSource :: Now
151154 } ;
@@ -213,6 +216,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
213216 let iter = lines. map_while ( Result :: ok) . map ( parse_date) ;
214217 Box :: new ( iter)
215218 }
219+ DateSource :: FileMtime ( ref path) => {
220+ let metadata = std:: fs:: metadata ( path)
221+ . map_err_context ( || path. as_os_str ( ) . to_string_lossy ( ) . to_string ( ) ) ?;
222+ let mtime = metadata. modified ( ) ?;
223+ let ts = Timestamp :: try_from ( mtime) . map_err ( |e| {
224+ USimpleError :: new (
225+ 1 ,
226+ translate ! ( "date-error-cannot-set-date" , "path" => path. to_string_lossy( ) , "error" => e) ,
227+ )
228+ } ) ?;
229+ let date = ts. to_zoned ( TimeZone :: try_system ( ) . unwrap_or ( TimeZone :: UTC ) ) ;
230+ let iter = std:: iter:: once ( Ok ( date) ) ;
231+ Box :: new ( iter)
232+ }
216233 DateSource :: Now => {
217234 let iter = std:: iter:: once ( Ok ( now) ) ;
218235 Box :: new ( iter)
0 commit comments