Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Create your online store today with Shopify

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth

Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Disclosure: My content contains affiliate links.

43,563 questions

56,781 answers

573 users

How to convert multiple date formats to YYYY-MM-DD in Rust

1 Answer

0 votes
use chrono::{NaiveDate};

/*
Architecture notes:
- Uses chrono’s NaiveDate for strict date parsing without auto-correction.
- Modular design: normalize_date orchestrates parsing; try_format handles each layout.
- Strict validation: NaiveDate::parse_from_str rejects impossible dates (e.g., Feb 30).
- Complexity: O(n) per date, where n = number of formats attempted.
- Memory: minimal; only small structs created.
- Security: avoids unsafe parsing; relies on trusted standard library + chrono.
- Pitfalls: ambiguous formats (e.g., 7/5/2026). Here we treat it as MM/DD/YYYY.
- Error handling: invalid or unsupported formats return None.
- Tests in main cover valid, invalid, and edge cases.
*/

// Try parsing with a specific format; return None if invalid.
fn try_format(input: &str, fmt: &str) -> Option<NaiveDate> {
    NaiveDate::parse_from_str(input, fmt).ok()
}

// Normalize a date string to YYYY-MM-DD or return None.
fn normalize_date(raw: &str) -> Option<String> {
    // Clean quotes and whitespace.
    let clean = raw.trim().trim_matches('"').trim_matches('\'');

    // Supported formats (chrono uses %m/%d/%Y style patterns).
    let formats = [
        "%m/%d/%Y",      // 05/01/2024
        "%m-%d-%Y",      // 12-31-2023
        "%Y.%m.%d",      // 2024.02.09
        "%B %d, %Y",     // January 5, 2024
        "%Y/%m/%d",      // 2024/09/17
        "%Y-%m-%d",      // 2024-09-17
        "%d %b %Y",      // 25 Dec 2025, 6 Jan 2025
        "%b %d, %Y",     // Jan 7, 2025
        "%d %B %Y",      // 8 January 2025
        "%m/%d/%Y",      // 7/5/2026 (non-zero-padded also works)
    ];

    // Try each explicit format.
    for fmt in formats {
        if let Some(date) = try_format(clean, fmt) {
            return Some(date.format("%Y-%m-%d").to_string());
        }
    }

    // No fallback natural-language parsing in Rust std; chrono does not guess formats.
    None
}

fn main() {
    let tests = [
        "05/01/2024",
        "12-31-2023",
        "2024.02.09",
        "January 5, 2024",
        "2024/09/17",
        "2024-09-17",
        "25 Dec 2025",
        "6 Jan 2025",
        "Jan 7, 2025",
        "8 January 2025",
        "7/5/2026",
        "BadFormat",
        "Feb 30, 2024",
        "April 31, 2024",
    ];

    for t in tests {
        match normalize_date(t) {
            Some(result) => println!("Input: {:<15} => Output: {}", t, result),
            None => println!("Input: {:<15} => Output: INVALID", t),
        }
    }
}



/*
run:

Input: 05/01/2024      => Output: 2024-05-01
Input: 12-31-2023      => Output: 2023-12-31
Input: 2024.02.09      => Output: 2024-02-09
Input: January 5, 2024 => Output: 2024-01-05
Input: 2024/09/17      => Output: 2024-09-17
Input: 2024-09-17      => Output: 2024-09-17
Input: 25 Dec 2025     => Output: 2025-12-25
Input: 6 Jan 2025      => Output: 2025-01-06
Input: Jan 7, 2025     => Output: 2025-01-07
Input: 8 January 2025  => Output: 2025-01-08
Input: 7/5/2026        => Output: 2026-07-05
Input: BadFormat       => Output: INVALID
Input: Feb 30, 2024    => Output: INVALID
Input: April 31, 2024  => Output: INVALID

*/

 



answered Sep 25 by avibootz

Related questions

...