@@ -205,15 +205,35 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
205205 // Iterate over all dates - whether it's a single date or a file.
206206 let dates: Box < dyn Iterator < Item = _ > > = match settings. date_source {
207207 DateSource :: Human ( ref input) => {
208+ // GNU compatibility (Military timezone 'J'):
209+ // 'J' is reserved for local time in military timezones.
210+ // GNU date accepts it and treats it as midnight today (00:00:00).
211+ let is_military_j = input. eq_ignore_ascii_case ( "j" ) ;
212+
208213 // GNU compatibility (Pure numbers in date strings):
209214 // - Manual: https://www.gnu.org/software/coreutils/manual/html_node/Pure-numbers-in-date-strings.html
210- // - Semantics: a pure decimal number denotes today’ s time-of-day (HH or HHMM).
215+ // - Semantics: a pure decimal number denotes today' s time-of-day (HH or HHMM).
211216 // Examples: "0"/"00" => 00:00 today; "7"/"07" => 07:00 today; "0700" => 07:00 today.
212217 // For all other forms, fall back to the general parser.
213218 let is_pure_digits =
214219 !input. is_empty ( ) && input. len ( ) <= 4 && input. chars ( ) . all ( |c| c. is_ascii_digit ( ) ) ;
215220
216- let date = if is_pure_digits {
221+ let date = if is_military_j {
222+ // Treat 'J' as midnight today (00:00:00) in local time
223+ let date_part =
224+ strtime:: format ( "%F" , & now) . unwrap_or_else ( |_| String :: from ( "1970-01-01" ) ) ;
225+ let offset = if settings. utc {
226+ String :: from ( "+00:00" )
227+ } else {
228+ strtime:: format ( "%:z" , & now) . unwrap_or_default ( )
229+ } ;
230+ let composed = if offset. is_empty ( ) {
231+ format ! ( "{date_part} 00:00" )
232+ } else {
233+ format ! ( "{date_part} 00:00 {offset}" )
234+ } ;
235+ parse_date ( composed)
236+ } else if is_pure_digits {
217237 // Derive HH and MM from the input
218238 let ( hh_opt, mm_opt) = if input. len ( ) <= 2 {
219239 ( input. parse :: < u32 > ( ) . ok ( ) , Some ( 0u32 ) )
0 commit comments