parseDateValueFast quickly parses a date string to unix timestamp Returns 0 for invalid dates with fast pre-checks
(s string)
| 396 | // parseDateValueFast quickly parses a date string to unix timestamp |
| 397 | // Returns 0 for invalid dates with fast pre-checks |
| 398 | func parseDateValueFast(s string) int64 { |
| 399 | s = strings.TrimSpace(s) |
| 400 | |
| 401 | // Fast rejection checks |
| 402 | if s == "" || s == "NA" || s == "N/A" || s == "null" { |
| 403 | return 0 |
| 404 | } |
| 405 | |
| 406 | // Dates are typically 8-30 characters |
| 407 | if len(s) < 8 || len(s) > 30 { |
| 408 | return 0 |
| 409 | } |
| 410 | |
| 411 | // Must contain date separators |
| 412 | if !strings.ContainsAny(s, "-/.:T ") { |
| 413 | return 0 |
| 414 | } |
| 415 | |
| 416 | // Must contain at least one digit |
| 417 | hasDigit := false |
| 418 | for _, c := range s { |
| 419 | if c >= '0' && c <= '9' { |
| 420 | hasDigit = true |
| 421 | break |
| 422 | } |
| 423 | } |
| 424 | if !hasDigit { |
| 425 | return 0 |
| 426 | } |
| 427 | |
| 428 | // Try common date formats (most common first for performance) |
| 429 | formats := []string{ |
| 430 | "2006-01-02", // ISO date: 2024-10-17 |
| 431 | "2006-01-02 15:04:05", // ISO datetime: 2024-10-17 15:30:00 |
| 432 | "01/02/2006", // US date: 10/17/2024 |
| 433 | "02/01/2006", // EU date: 17/10/2024 |
| 434 | "2006/01/02", // Alt ISO: 2024/10/17 |
| 435 | time.RFC3339, // RFC3339: 2024-10-17T15:30:00Z |
| 436 | "2006-01-02T15:04:05", // ISO8601 without timezone |
| 437 | "Jan 02, 2006", // Mon DD, YYYY |
| 438 | "January 02, 2006", // Month DD, YYYY |
| 439 | "02-Jan-2006", // DD-Mon-YYYY |
| 440 | "02 Jan 2006", // DD Mon YYYY |
| 441 | "2006.01.02", // Dotted date |
| 442 | } |
| 443 | |
| 444 | for _, format := range formats { |
| 445 | if t, err := time.Parse(format, s); err == nil { |
| 446 | return t.Unix() |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | return 0 |
| 451 | } |
| 452 | |
| 453 | // getCol returns the ith column data as a string slice |
| 454 | // Uses pointer receiver to avoid copying mutex |
no outgoing calls