@@ -268,38 +268,93 @@ fn parse_tz_offset(args: &[String]) -> Option<i32> {
268268}
269269
270270/// Auto-detect timezone offset from C++ baseline file.
271- /// Extracts a date from the baseline and determines PDT vs PST based on Pacific
272- /// DST rules. Pacific DST: 2nd Sunday of March 2:00 AM to 1st Sunday of
273- /// November 2:00 AM
271+ /// Finds the MOST RECENT date (capture date) and determines PDT vs PST.
272+ /// Pacific DST: 2nd Sunday of March to 1st Sunday of November
274273fn detect_tz_from_baseline ( baseline_path : & Path ) -> i32 {
275- // Read first few lines to find a data line with a timestamp
276274 let file = match std:: fs:: File :: open ( baseline_path) {
277275 Ok ( f) => f,
278- Err ( _) => return -7 , // Default to PDT if can't read
276+ Err ( _) => return -7 ,
279277 } ;
280278 let reader = std:: io:: BufReader :: new ( file) ;
281279
282- for line in std:: io:: BufRead :: lines ( reader) . take ( 10 ) . flatten ( ) {
283- // Look for a timestamp pattern: YYYY-MM-DD HH:MM:SS
284- if let Some ( date_match) = extract_date_from_line ( & line) {
285- let offset = pacific_tz_offset ( date_match. 0 , date_match. 1 , date_match. 2 ) ;
286- println ! (
287- "Auto-detected timezone from baseline date {}-{:02}-{:02}: {} ({})" ,
288- date_match. 0 ,
289- date_match. 1 ,
290- date_match. 2 ,
291- offset,
292- if offset == -7 { "PDT" } else { "PST" }
293- ) ;
294- return offset;
280+ let mut most_recent: Option < ( i32 , u32 , u32 ) > = None ;
281+
282+ // Scan first 20 lines to find the most recent date (likely capture date)
283+ for line in std:: io:: BufRead :: lines ( reader) . take ( 20 ) . flatten ( ) {
284+ for date in extract_all_dates_from_line ( & line) {
285+ if let Some ( current) = most_recent {
286+ // Keep the more recent date
287+ if date. 0 > current. 0
288+ || ( date. 0 == current. 0 && date. 1 > current. 1 )
289+ || ( date. 0 == current. 0 && date. 1 == current. 1 && date. 2 > current. 2 )
290+ {
291+ most_recent = Some ( date) ;
292+ }
293+ } else {
294+ most_recent = Some ( date) ;
295+ }
295296 }
296297 }
297298
299+ if let Some ( ( year, month, day) ) = most_recent {
300+ let offset = pacific_tz_offset ( year, month, day) ;
301+ println ! (
302+ "Auto-detected timezone from capture date {}-{:02}-{:02}: {} ({})" ,
303+ year,
304+ month,
305+ day,
306+ offset,
307+ if offset == -7 { "PDT" } else { "PST" }
308+ ) ;
309+ return offset;
310+ }
311+
298312 println ! ( "Could not auto-detect timezone, defaulting to -7 (PDT)" ) ;
299313 -7
300314}
301315
302- /// Extract (year, month, day) from a CSV line containing a timestamp.
316+ /// Extract ALL (year, month, day) tuples from a CSV line.
317+ fn extract_all_dates_from_line ( line : & str ) -> Vec < ( i32 , u32 , u32 ) > {
318+ let mut dates = Vec :: new ( ) ;
319+ let bytes = line. as_bytes ( ) ;
320+ let mut i = 0 ;
321+ while i + 10 <= bytes. len ( ) {
322+ if bytes[ i] . is_ascii_digit ( )
323+ && bytes[ i + 1 ] . is_ascii_digit ( )
324+ && bytes[ i + 2 ] . is_ascii_digit ( )
325+ && bytes[ i + 3 ] . is_ascii_digit ( )
326+ && bytes[ i + 4 ] == b'-'
327+ && bytes[ i + 5 ] . is_ascii_digit ( )
328+ && bytes[ i + 6 ] . is_ascii_digit ( )
329+ && bytes[ i + 7 ] == b'-'
330+ && bytes[ i + 8 ] . is_ascii_digit ( )
331+ && bytes[ i + 9 ] . is_ascii_digit ( )
332+ {
333+ if let ( Ok ( year) , Ok ( month) , Ok ( day) ) = (
334+ line[ i..i + 4 ] . parse :: < i32 > ( ) ,
335+ line[ i + 5 ..i + 7 ] . parse :: < u32 > ( ) ,
336+ line[ i + 8 ..i + 10 ] . parse :: < u32 > ( ) ,
337+ ) {
338+ if year >= 2000
339+ && year <= 2100
340+ && month >= 1
341+ && month <= 12
342+ && day >= 1
343+ && day <= 31
344+ {
345+ dates. push ( ( year, month, day) ) ;
346+ }
347+ }
348+ i += 10 ; // Skip past this date
349+ } else {
350+ i += 1 ;
351+ }
352+ }
353+ dates
354+ }
355+
356+ /// Extract first (year, month, day) from a CSV line (kept for compatibility).
357+ #[ allow( dead_code) ]
303358fn extract_date_from_line ( line : & str ) -> Option < ( i32 , u32 , u32 ) > {
304359 // Look for pattern: YYYY-MM-DD (4 digits, dash, 2 digits, dash, 2 digits)
305360 let bytes = line. as_bytes ( ) ;
0 commit comments