@@ -285,6 +285,27 @@ fn parse_military_timezone_with_offset(s: &str) -> Option<(i32, DayDelta)> {
285285pub fn uumain ( args : impl uucore:: Args ) -> UResult < ( ) > {
286286 let matches = uucore:: clap_localization:: handle_clap_result ( uu_app ( ) , args) ?;
287287
288+ let date_source = if let Some ( date_os) = matches. get_one :: < std:: ffi:: OsString > ( OPT_DATE ) {
289+ // Convert OsString to String, handling invalid UTF-8 with GNU-compatible error
290+ let date = date_os. to_str ( ) . ok_or_else ( || {
291+ let bytes = date_os. as_encoded_bytes ( ) ;
292+ let escaped_str = escape_invalid_bytes ( bytes) ;
293+ USimpleError :: new ( 1 , format ! ( "invalid date '{escaped_str}'" ) )
294+ } ) ?;
295+ DateSource :: Human ( date. into ( ) )
296+ } else if let Some ( file) = matches. get_one :: < String > ( OPT_FILE ) {
297+ match file. as_ref ( ) {
298+ "-" => DateSource :: Stdin ,
299+ _ => DateSource :: File ( file. into ( ) ) ,
300+ }
301+ } else if let Some ( file) = matches. get_one :: < String > ( OPT_REFERENCE ) {
302+ DateSource :: FileMtime ( file. into ( ) )
303+ } else if matches. get_flag ( OPT_RESOLUTION ) {
304+ DateSource :: Resolution
305+ } else {
306+ DateSource :: Now
307+ } ;
308+
288309 // Check for extra operands (multiple positional arguments)
289310 if let Some ( formats) = matches. get_many :: < String > ( OPT_FORMAT ) {
290311 let format_args: Vec < & String > = formats. collect ( ) ;
@@ -298,9 +319,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
298319
299320 let format = if let Some ( form) = matches. get_one :: < String > ( OPT_FORMAT ) {
300321 if !form. starts_with ( '+' ) {
322+ // if an optional Format String was found but the user has not provided an input date
323+ // GNU prints an invalid date Error
324+ if !matches ! ( date_source, DateSource :: Human ( _) ) {
325+ return Err ( USimpleError :: new (
326+ 1 ,
327+ translate ! ( "date-error-invalid-date" , "date" => form) ,
328+ ) ) ;
329+ }
330+ // If the user did provide an input date with the --date flag and the Format String is
331+ // not starting with '+' GNU prints the missing '+' error message
301332 return Err ( USimpleError :: new (
302333 1 ,
303- translate ! ( "date-error-invalid-date " , "date " => form) ,
334+ translate ! ( "date-error-format-missing-plus " , "arg " => form) ,
304335 ) ) ;
305336 }
306337 let form = form[ 1 ..] . to_string ( ) ;
@@ -333,27 +364,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
333364 Zoned :: now ( )
334365 } ;
335366
336- let date_source = if let Some ( date_os) = matches. get_one :: < std:: ffi:: OsString > ( OPT_DATE ) {
337- // Convert OsString to String, handling invalid UTF-8 with GNU-compatible error
338- let date = date_os. to_str ( ) . ok_or_else ( || {
339- let bytes = date_os. as_encoded_bytes ( ) ;
340- let escaped_str = escape_invalid_bytes ( bytes) ;
341- USimpleError :: new ( 1 , format ! ( "invalid date '{escaped_str}'" ) )
342- } ) ?;
343- DateSource :: Human ( date. into ( ) )
344- } else if let Some ( file) = matches. get_one :: < String > ( OPT_FILE ) {
345- match file. as_ref ( ) {
346- "-" => DateSource :: Stdin ,
347- _ => DateSource :: File ( file. into ( ) ) ,
348- }
349- } else if let Some ( file) = matches. get_one :: < String > ( OPT_REFERENCE ) {
350- DateSource :: FileMtime ( file. into ( ) )
351- } else if matches. get_flag ( OPT_RESOLUTION ) {
352- DateSource :: Resolution
353- } else {
354- DateSource :: Now
355- } ;
356-
357367 let set_to = match matches
358368 . get_one :: < String > ( OPT_SET )
359369 . map ( |s| parse_date ( s, & now, DebugOptions :: new ( debug_mode, true ) ) )
0 commit comments