Ejemplos de Fecha y Hora Web Rust

Ejemplos de fecha y hora Web Rust incluyendo obtener hora actual, formateo y análisis

💻 Obtener Hora Actual rust

🟢 simple ⭐⭐

Obtener la hora actual del sistema en varios formatos usando chrono crate

⏱️ 15 min 🏷️ rust, web, datetime
Prerequisites: Basic Rust, chrono crate
// Web Rust Get Current Time Examples
// Working with current time using chrono crate
//
// Add to Cargo.toml:
// [dependencies]
// chrono = "0.4"

use chrono::{Local, Utc, DateTime, Local as DateTimeLocal};

// 1. Get Current Time (UTC)

/// Get current UTC time as DateTime
fn get_current_utc() -> DateTime<Utc> {
    Utc::now()
}

/// Get current UTC timestamp (seconds since epoch)
fn get_current_timestamp() -> i64 {
    Utc::now().timestamp()
}

/// Get current UTC timestamp (milliseconds since epoch)
fn get_current_timestamp_millis() -> i64 {
    Utc::now().timestamp_millis()
}

/// Get current UTC timestamp (microseconds since epoch)
fn get_current_timestamp_micros() -> i64 {
    Utc::now().timestamp_micros()
}

// 2. Get Current Time (Local)

/// Get current local time
fn get_current_local() -> DateTime<DateTimeLocal> {
    Local::now()
}

/// Get current local date
fn get_current_local_date() -> chrono::Date<chrono::Local> {
    Local::now().date_naive()
}

/// Get current local time
fn get_current_local_time() -> chrono::NaiveTime {
    Local::now().time()
}

// 3. Time Components

/// Get current year
fn get_current_year() -> i32 {
    Local::now().year()
}

/// Get current month (1-12)
fn get_current_month() -> u32 {
    Local::now().month()
}

/// Get current day (1-31)
fn get_current_day() -> u32 {
    Local::now().day()
}

/// Get current hour (0-23)
fn get_current_hour() -> u32 {
    Local::now().hour()
}

/// Get current minute (0-59)
fn get_current_minute() -> u32 {
    Local::now().minute()
}

/// Get current second (0-59)
fn get_current_second() -> u32 {
    Local::now().second()
}

// 4. Get All Components

/// Structure to hold time components
#[derive(Debug)]
struct TimeComponents {
    year: i32,
    month: u32,
    day: u32,
    hour: u32,
    minute: u32,
    second: u32,
    weekday: String,
    ordinal: u32,
}

/// Get all time components
fn get_time_components() -> TimeComponents {
    let now = Local::now();
    TimeComponents {
        year: now.year(),
        month: now.month(),
        day: now.day(),
        hour: now.hour(),
        minute: now.minute(),
        second: now.second(),
        weekday: now.format("%A").to_string(),
        ordinal: now.ordinal(),
    }
}

// 5. Week Information

/// Get current weekday (Monday=1, Sunday=7)
fn get_current_weekday() -> u32 {
    Local::now().weekday() as u32
}

/// Get weekday name
fn get_current_weekday_name() -> String {
    Local::now().format("%A").to_string()
}

/// Get weekday abbreviation
fn get_current_weekday_abbr() -> String {
    Local::now().format("%a").to_string()
}

/// Get ISO week number
fn get_current_iso_week() -> u32 {
    Local::now().iso_week().week()
}

/// Get ISO year
fn get_current_iso_year() -> i32 {
    Local::now().iso_week().year()
}

// 6. Day of Year

/// Get day of year (1-366)
fn get_current_day_of_year() -> u32 {
    Local::now().ordinal()
}

/// Get days remaining in year
fn get_days_remaining_in_year() -> i64 {
    let now = Local::now();
    let year = now.year();
    let start_of_next_year = chrono::NaiveDate::from_ymd_opt(year + 1, 1, 1)
        .unwrap()
        .and_hms_opt(0, 0, 0)
        .unwrap();
    let and_time = chrono::Local::now().naive_local();

    (start_of_next_year - and_time.date_naive()).num_days()
}

/// Get percentage of year passed
fn get_year_progress() -> f64 {
    let now = Local::now();
    let start_of_year = chrono::NaiveDate::from_ymd_opt(now.year(), 1, 1).unwrap();
    let current_date = now.date_naive();
    let days_passed = (current_date - start_of_year).num_days() as f64;

    let is_leap_year = (now.year() % 4 == 0 && now.year() % 100 != 0) || (now.year() % 400 == 0);
    let days_in_year = if is_leap_year { 366.0 } else { 365.0 };

    (days_passed / days_in_year) * 100.0
}

// 7. Timezone Information

/// Get timezone name
fn get_timezone_name() -> String {
    Local::now().format("%Z").to_string()
}

/// Get timezone offset
fn get_timezone_offset() -> String {
    Local::now().format("%z").to_string()
}

// 8. Comparison Functions

/// Check if current time is before a given time
fn is_before(timestamp: i64) -> bool {
    get_current_timestamp() < timestamp
}

/// Check if current time is after a given time
fn is_after(timestamp: i64) -> bool {
    get_current_timestamp() > timestamp
}

/// Calculate age from birth timestamp
fn calculate_age(birth_timestamp: i64) -> i32 {
    let now = Utc::now();
    let birth = DateTime::from_timestamp(birth_timestamp, 0).unwrap();
    let age_years = now.signed_duration_since(birth).num_days() / 365;
    age_years as i32
}

// 9. Utility Functions

/// Check if current year is leap year
fn is_leap_year() -> bool {
    let year = Local::now().year();
    (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}

/// Get days in current month
fn get_days_in_current_month() -> u32 {
    let now = Local::now();
    chrono::NaiveDate::from_ymd_opt(
        now.year(),
        now.month() + 1,
        1
    )
        .unwrap()
        .pred()
        .day()
}

/// Get quarter of year (1-4)
fn get_current_quarter() -> u32 {
    let month = Local::now().month();
    (month - 1) / 3 + 1
}

// 10. Time since

/// Get time elapsed since timestamp (human-readable)
fn time_elapsed_since(timestamp: i64) -> String {
    let now = Utc::now();
    let then = DateTime::from_timestamp(timestamp, 0).unwrap();
    let duration = now.signed_duration_since(then);

    if duration.num_days() > 0 {
        format!("{} days ago", duration.num_days())
    } else if duration.num_hours() > 0 {
        format!("{} hours ago", duration.num_hours())
    } else if duration.num_minutes() > 0 {
        format!("{} minutes ago", duration.num_minutes())
    } else {
        format!("{} seconds ago", duration.num_seconds())
    }
}

// Usage Examples
fn main() {
    println!("=== Web Rust Get Current Time Examples ===\n");

    // 1. UTC time
    println!("--- 1. Current UTC Time ---");
    println!("UTC DateTime: {}", get_current_utc());
    println!("Timestamp (seconds): {}", get_current_timestamp());
    println!("Timestamp (millis): {}", get_current_timestamp_millis());
    println!("Timestamp (micros): {}", get_current_timestamp_micros());

    // 2. Local time
    println!("\n--- 2. Current Local Time ---");
    println!("Local DateTime: {}", get_current_local());
    println!("Local Date: {}", get_current_local_date());
    println!("Local Time: {}", get_current_local_time());

    // 3. Time components
    println!("\n--- 3. Time Components ---");
    println!("Year: {}", get_current_year());
    println!("Month: {}", get_current_month());
    println!("Day: {}", get_current_day());
    println!("Hour: {}", get_current_hour());
    println!("Minute: {}", get_current_minute());
    println!("Second: {}", get_current_second());

    // 4. All components
    println!("\n--- 4. All Time Components ---");
    println!("{:?}", get_time_components());

    // 5. Week information
    println!("\n--- 5. Week Information ---");
    println!("Weekday (number): {}", get_current_weekday());
    println!("Weekday name: {}", get_current_weekday_name());
    println!("Weekday abbr: {}", get_current_weekday_abbr());
    println!("ISO week: {}", get_current_iso_week());
    println!("ISO year: {}", get_current_iso_year());

    // 6. Day of year
    println!("\n--- 6. Day of Year ---");
    println!("Day of year: {}", get_current_day_of_year());
    println!("Days remaining: {}", get_days_remaining_in_year());
    println!("Year progress: {:.2}%", get_year_progress());

    // 7. Timezone
    println!("\n--- 7. Timezone ---");
    println!("Timezone name: {}", get_timezone_name());
    println!("Timezone offset: {}", get_timezone_offset());

    // 8. Comparison
    println!("\n--- 8. Comparison ---");
    let past_timestamp = get_current_timestamp() - 3600;
    println!("Is before 1 hour ago: {}", is_before(past_timestamp));
    println!("Is after 1 hour ago: {}", is_after(past_timestamp));

    // 9. Utilities
    println!("\n--- 9. Utilities ---");
    println!("Is leap year: {}", is_leap_year());
    println!("Days in month: {}", get_days_in_current_month());
    println!("Quarter: {}", get_current_quarter());

    // 10. Time elapsed
    println!("\n--- 10. Time Elapsed ---");
    let past = get_current_timestamp() - 3661;
    println!("Since 1 hour 1 minute ago: {}", time_elapsed_since(past));

    let birth_timestamp = 946684800; // 2000-01-01
    println!("Age of someone born on 2000-01-01: {} years", calculate_age(birth_timestamp));

    println!("\n=== All Get Current Time Examples Completed ===");
}

💻 Formateo de Hora rust

🟡 intermediate ⭐⭐⭐

Formatear objetos DateTime a cadenas con varios formatos y patrones personalizados

⏱️ 20 min 🏷️ rust, web, datetime
Prerequisites: Intermediate Rust, chrono crate
// Web Rust Time Formatting Examples
// Format DateTime to string representations
//
// Add to Cargo.toml:
// [dependencies]
// chrono = "0.4"

use chrono::{Local, Utc, DateTime};

// 1. Predefined Formats

/// Format as ISO 8601 (UTC)
fn format_iso8601_utc(dt: DateTime<Utc>) -> String {
    dt.format("%Y-%m-%dT%H:%M:%SZ").to_string()
}

/// Format as ISO 8601 (local)
fn format_iso8601_local(dt: DateTime<Local>) -> String {
    dt.format("%Y-%m-%dT%H:%M:%S%z").to_string()
}

/// Format as RFC 2822
fn format_rfc2822(dt: DateTime<Local>) -> String {
    dt.format("%a, %d %b %Y %H:%M:%S %z").to_string()
}

/// Format as RFC 3339
fn format_rfc3339(dt: DateTime<Utc>) -> String {
    dt.format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string()
}

// 2. Date Formats

/// Format as date only (YYYY-MM-DD)
fn format_date_only(dt: DateTime<Local>) -> String {
    dt.format("%Y-%m-%d").to_string()
}

/// Format as US date (MM/DD/YYYY)
fn format_date_us(dt: DateTime<Local>) -> String {
    dt.format("%m/%d/%Y").to_string()
}

/// Format as European date (DD/MM/YYYY)
fn format_date_eu(dt: DateTime<Local>) -> String {
    dt.format("%d/%m/%Y").to_string()
}

/// Format as long date (e.g., "Monday, January 1, 2024")
fn format_long_date(dt: DateTime<Local>) -> String {
    dt.format("%A, %B %d, %Y").to_string()
}

/// Format as short date (e.g., "Jan 1, 2024")
fn format_short_date(dt: DateTime<Local>) -> String {
    dt.format("%b %d, %Y").to_string()
}

// 3. Time Formats

/// Format as time only (24-hour)
fn format_time_24h(dt: DateTime<Local>) -> String {
    dt.format("%H:%M:%S").to_string()
}

/// Format as time only (12-hour)
fn format_time_12h(dt: DateTime<Local>) -> String {
    dt.format("%I:%M:%S %p").to_string()
}

/// Format as compact time (HH:MM)
fn format_time_compact(dt: DateTime<Local>) -> String {
    dt.format("%H:%M").to_string()
}

// 4. Combined Date-Time Formats

/// Format as common format (YYYY-MM-DD HH:MM:SS)
fn format_common(dt: DateTime<Local>) -> String {
    dt.format("%Y-%m-%d %H:%M:%S").to_string()
}

/// Format as human-readable
fn format_human_readable(dt: DateTime<Local>) -> String {
    dt.format("%A, %B %d, %Y at %I:%M %p").to_string()
}

/// Format as compact datetime
fn format_compact(dt: DateTime<Local>) -> String {
    dt.format("%Y%m%d_%H%M%S").to_string()
}

// 5. Custom Components

/// Format with weekday
fn format_with_weekday(dt: DateTime<Local>) -> String {
    dt.format("%a, %Y-%m-%d").to_string()
}

/// Format with week number
fn format_with_week(dt: DateTime<Local>) -> String {
    dt.format("%Y-W%V-%u").to_string()
}

/// Format with quarter
fn format_with_quarter(dt: DateTime<Local>) -> String {
    let quarter = (dt.month() - 1) / 3 + 1;
    format!("{}-Q{}", dt.year(), quarter)
}

/// Format with ordinal day
fn format_with_ordinal(dt: DateTime<Local>) -> String {
    let day = dt.day();
    let suffix = if day % 100 >= 11 && day % 100 <= 13 {
        "th"
    } else {
        match day % 10 {
            1 => "st",
            2 => "nd",
            3 => "rd",
            _ => "th",
        }
    };
    format!("{} {}{} {}", dt.format("%B"), day, suffix, dt.year())
}

// 6. Relative Formats

/// Format as "Today at HH:MM"
fn format_today_at(dt: DateTime<Local>) -> String {
    format!("Today at {}", dt.format("%I:%M %p"))
}

/// Format as "Month Day, Year at HH:MM AM/PM"
fn format_full_at(dt: DateTime<Local>) -> String {
    format!("{} at {}", dt.format("%B %d, %Y"), dt.format("%I:%M %p"))
}

// 7. Locale-Aware Formats (simplified)

/// Format for US locale
fn format_locale_us(dt: DateTime<Local>) -> String {
    dt.format("%B %d, %Y %I:%M:%S %p").to_string()
}

/// Format for European locale
fn format_locale_eu(dt: DateTime<Local>) -> String {
    dt.format("%d %B %Y %H:%M:%S").to_string()
}

/// Format for ISO locale
fn format_locale_iso(dt: DateTime<Local>) -> String {
    dt.format("%Y-%m-%d %H:%M").to_string()
}

// 8. Log/Debug Formats

/// Format for logging (compact and sortable)
fn format_log(dt: DateTime<Local>) -> String {
    dt.format("%Y%m%d-%H%M%S").to_string()
}

/// Format for filenames
fn format_filename(dt: DateTime<Local>) -> String {
    dt.format("%Y%m%d_%H%M%S").to_string()
}

/// Format for HTTP headers
fn format_http_date(dt: DateTime<Local>) -> String {
    dt.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
}

// 9. Special Formats

/// Format as Unix timestamp string
fn format_timestamp_string(dt: DateTime<Utc>) -> String {
    dt.timestamp().to_string()
}

/// Format as duration from now
fn format_duration_from_now(dt: DateTime<Local>) -> String {
    let now = Local::now();
    let duration = now.signed_duration_since(dt);

    if duration.num_days() > 0 {
        format!("{} days ago", duration.num_days())
    } else if duration.num_hours() > 0 {
        format!("{} hours ago", duration.num_hours())
    } else if duration.num_minutes() > 0 {
        format!("{} minutes ago", duration.num_minutes())
    } else {
        format!("{} seconds ago", duration.num_seconds())
    }
}

/// Format as age
fn format_age(dt: DateTime<Local>) -> String {
    let now = Local::now();
    let duration = now.signed_duration_since(dt);
    let years = duration.num_days() / 365;
    format!("{} years", years)
}

// 10. Custom Format Function

/// Format with custom pattern
fn format_custom(dt: DateTime<Local>, pattern: &str) -> String {
    dt.format(pattern).to_string()
}

/// Format with multiple options
#[derive(Debug)]
struct FormatOptions {
    include_year: bool,
    include_month: bool,
    include_day: bool,
    include_time: bool,
    separator: String,
}

fn format_with_options(dt: DateTime<Local>, options: &FormatOptions) -> String {
    let mut parts = Vec::new();

    if options.include_year {
        parts.push(dt.format("%Y").to_string());
    }
    if options.include_month {
        parts.push(dt.format("%m").to_string());
    }
    if options.include_day {
        parts.push(dt.format("%d").to_string());
    }
    if options.include_time {
        parts.push(dt.format("%H:%M").to_string());
    }

    parts.join(&options.separator)
}

// Usage Examples
fn main() {
    println!("=== Web Rust Time Formatting Examples ===\n");

    let utc_now = Utc::now();
    let local_now = Local::now();

    // 1. Predefined formats
    println!("--- 1. Predefined Formats ---");
    println!("ISO 8601 (UTC): {}", format_iso8601_utc(utc_now));
    println!("ISO 8601 (local): {}", format_iso8601_local(local_now));
    println!("RFC 2822: {}", format_rfc2822(local_now));
    println!("RFC 3339: {}", format_rfc3339(utc_now));

    // 2. Date formats
    println!("\n--- 2. Date Formats ---");
    println!("Date only: {}", format_date_only(local_now));
    println!("US date: {}", format_date_us(local_now));
    println!("EU date: {}", format_date_eu(local_now));
    println!("Long date: {}", format_long_date(local_now));
    println!("Short date: {}", format_short_date(local_now));

    // 3. Time formats
    println!("\n--- 3. Time Formats ---");
    println!("Time (24h): {}", format_time_24h(local_now));
    println!("Time (12h): {}", format_time_12h(local_now));
    println!("Time (compact): {}", format_time_compact(local_now));

    // 4. Combined formats
    println!("\n--- 4. Combined Formats ---");
    println!("Common: {}", format_common(local_now));
    println!("Human readable: {}", format_human_readable(local_now));
    println!("Compact: {}", format_compact(local_now));

    // 5. Custom components
    println!("\n--- 5. Custom Components ---");
    println!("With weekday: {}", format_with_weekday(local_now));
    println!("With week: {}", format_with_week(local_now));
    println!("With quarter: {}", format_with_quarter(local_now));
    println!("With ordinal: {}", format_with_ordinal(local_now));

    // 6. Locale formats
    println!("\n--- 6. Locale Formats ---");
    println!("US locale: {}", format_locale_us(local_now));
    println!("EU locale: {}", format_locale_eu(local_now));
    println!("ISO locale: {}", format_locale_iso(local_now));

    // 7. Log/debug formats
    println!("\n--- 7. Log/Debug Formats ---");
    println!("Log format: {}", format_log(local_now));
    println!("Filename: {}", format_filename(local_now));
    println!("HTTP date: {}", format_http_date(local_now));

    // 8. Special formats
    println!("\n--- 8. Special Formats ---");
    println!("Timestamp: {}", format_timestamp_string(utc_now));
    println!("From now: {}", format_duration_from_now(local_now));

    // 9. Custom format
    println!("\n--- 9. Custom Format ---");
    println!("Custom (Day/Month/Year): {}", format_custom(local_now, "%d/%m/%Y"));

    // 10. Options-based format
    println!("\n--- 10. Format with Options ---");
    let options = FormatOptions {
        include_year: true,
        include_month: true,
        include_day: true,
        include_time: true,
        separator: "-".to_string(),
    };
    println!("With options: {}", format_with_options(local_now, &options));

    println!("\n=== All Time Formatting Examples Completed ===");
}

💻 Análisis de Hora rust

🟡 intermediate ⭐⭐⭐

Analizar representaciones de cadena en objetos DateTime con varios formatos

⏱️ 25 min 🏷️ rust, web, datetime
Prerequisites: Intermediate Rust, chrono crate
// Web Rust Time Parsing Examples
// Parse strings into DateTime objects
//
// Add to Cargo.toml:
// [dependencies]
// chrono = "0.4"

use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc, ParseError};
use std::str::FromStr;

// 1. Parse ISO 8601

/// Parse ISO 8601 string to DateTime UTC
fn parse_iso8601_utc(s: &str) -> Result<DateTime<Utc>, ParseError> {
    s.parse::<DateTime<Utc>>()
}

/// Parse ISO 8601 string to DateTime Local
fn parse_iso8601_local(s: &str) -> Result<DateTime<Local>, ParseError> {
    s.parse::<DateTime<Local>>()
}

// 2. Parse Custom Formats

/// Parse date string (YYYY-MM-DD)
fn parse_date_only(s: &str) -> Result<NaiveDate, ParseError> {
    NaiveDate::from_str(s)
}

/// Parse time string (HH:MM:SS)
fn parse_time_only(s: &str) -> Result<NaiveTime, ParseError> {
    NaiveTime::from_str(s)
}

/// Parse datetime string (YYYY-MM-DD HH:MM:SS)
fn parse_datetime_naive(s: &str) -> Result<NaiveDateTime, ParseError> {
    NaiveDateTime::from_str(s)
}

/// Parse with custom format string
fn parse_custom_format(s: &str, format: &str) -> Result<NaiveDateTime, ParseError> {
    NaiveDateTime::parse_from_str(s, format)
}

// 3. Parse Common Formats

/// Parse US date format (MM/DD/YYYY)
fn parse_us_date(s: &str) -> Result<NaiveDate, ParseError> {
    NaiveDate::parse_from_str(s, "%m/%d/%Y")
}

/// Parse European date format (DD/MM/YYYY)
fn parse_eu_date(s: &str) -> Result<NaiveDate, ParseError> {
    NaiveDate::parse_from_str(s, "%d/%m/%Y")
}

/// Parse compact date (YYYYMMDD)
fn parse_compact_date(s: &str) -> Result<NaiveDate, ParseError> {
    NaiveDate::parse_from_str(s, "%Y%m%d")
}

/// Parse RFC 2822 datetime
fn parse_rfc2822(s: &str) -> Result<DateTime<Utc>, ParseError> {
    DateTime::parse_from_rfc2822(s)
}

/// Parse RFC 3339 datetime
fn parse_rfc3339(s: &str) -> Result<DateTime<Utc>, ParseError> {
    DateTime::parse_from_rfc3339(s)
}

// 4. Parse with Flexible Formats

/// Try multiple formats until one succeeds
fn parse_flexible(s: &str, formats: &[&str]) -> Option<NaiveDateTime> {
    for format in formats {
        if let Ok(dt) = NaiveDateTime::parse_from_str(s, format) {
            return Some(dt);
        }
    }
    None
}

/// Parse date with multiple format attempts
fn parse_date_flexible(s: &str) -> Option<NaiveDate> {
    let formats = ["%Y-%m-%d", "%m/%d/%Y", "%d/%m/%Y", "%Y%m%d", "%b %d, %Y"];
    for format in formats {
        if let Ok(d) = NaiveDate::parse_from_str(s, format) {
            return Some(d);
        }
    }
    None
}

// 5. Parse Unix Timestamp

/// Parse Unix timestamp (seconds)
fn parse_timestamp_seconds(timestamp: i64) -> Result<DateTime<Utc>, ParseError> {
    DateTime::from_timestamp(timestamp, 0)
        .ok_or_else(|| ParseError::from_kind(chrono::format::ParseErrorKind::OutOfRange))
}

/// Parse Unix timestamp (milliseconds)
fn parse_timestamp_millis(timestamp: i64) -> Result<DateTime<Utc>, ParseError> {
    let seconds = timestamp / 1000;
    let nanos = ((timestamp % 1000) * 1_000_000) as u32;
    DateTime::from_timestamp(seconds, nanos)
        .ok_or_else(|| ParseError::from_kind(chrono::format::ParseErrorKind::OutOfRange))
}

// 6. Parse Relative Time

/// Parse "X days ago"
fn parse_days_ago(s: &str) -> Option<NaiveDateTime> {
    let re = regex::Regex::new(r"(d+)s+days?s+ago").ok()?;
    let caps = re.captures(s)?;
    let days: i64 = caps.get(1)?.as_str().parse().ok()?;
    Some(Local::now().naive_local() - chrono::Duration::days(days))
}

/// Parse "X hours ago"
fn parse_hours_ago(s: &str) -> Option<NaiveDateTime> {
    let re = regex::Regex::new(r"(d+)s+hours?s+ago").ok()?;
    let caps = re.captures(s)?;
    let hours: i64 = caps.get(1)?.as_str().parse().ok()?;
    Some(Local::now().naive_local() - chrono::Duration::hours(hours))
}

/// Parse "X minutes ago"
fn parse_minutes_ago(s: &str) -> Option<NaiveDateTime> {
    let re = regex::Regex::new(r"(d+)s+minutes?s+ago").ok()?;
    let caps = re.captures(s)?;
    let minutes: i64 = caps.get(1)?.as_str().parse().ok()?;
    Some(Local::now().naive_local() - chrono::Duration::minutes(minutes))
}

// 7. Extract Date Components

/// Extract year from string
fn extract_year(s: &str) -> Option<u32> {
    let re = regex::Regex::new(r"(d{4})").ok()?;
    let caps = re.captures(s)?;
    caps.get(1)?.as_str().parse().ok()
}

/// Extract month from string
fn extract_month(s: &str) -> Option<u32> {
    let re = regex::Regex::new(r"(0?[1-9]|1[0-2])").ok()?;
    let caps = re.captures(s)?;
    caps.get(1)?.as_str().parse().ok()
}

// 8. Parse with Validation

/// Parse date and validate it's not in the future
fn parse_date_not_future(s: &str, format: &str) -> Result<NaiveDate, ParseError> {
    let date = NaiveDate::parse_from_str(s, format)?;
    let today = Local::now().date_naive();

    if date > today {
        return Err(ParseError::from_kind(chrono::format::ParseErrorKind::OutOfRange));
    }

    Ok(date)
}

/// Parse date and validate it's within range
fn parse_date_in_range(
    s: &str,
    format: &str,
    min: NaiveDate,
    max: NaiveDate,
) -> Result<NaiveDate, ParseError> {
    let date = NaiveDate::parse_from_str(s, format)?;

    if date < min || date > max {
        return Err(ParseError::from_kind(chrono::format::ParseErrorKind::OutOfRange));
    }

    Ok(date)
}

// 9. Parse and Convert

/// Parse string and convert to timezone
fn parse_and_convert_timezone(
    s: &str,
    format: &str,
) -> Result<DateTime<Utc>, ParseError> {
    let naive_dt = NaiveDateTime::parse_from_str(s, format)?;
    Ok(Local.from_local_naive(&naive_dt).earliest().unwrap().with_timezone(&Utc))
}

// 10. Batch Parsing

/// Parse multiple dates with same format
fn parse_multiple_dates(dates: &[String], format: &str) -> Vec<Result<NaiveDate, ParseError>> {
    dates.iter()
        .map(|s| NaiveDate::parse_from_str(s, format))
        .collect()
}

/// Parse and sort dates
fn parse_and_sort_dates(dates: &[String], format: &str) -> Vec<NaiveDate> {
    dates.iter()
        .filter_map(|s| NaiveDate::parse_from_str(s, format).ok())
        .collect::<Vec<_>>()
        .into_iter()
        .collect::<Vec<_>>()
}

// Usage Examples
fn main() {
    println!("=== Web Rust Time Parsing Examples ===\n");

    // 1. Parse ISO 8601
    println!("--- 1. Parse ISO 8601 ---");
    match parse_iso8601_utc("2024-01-15T10:30:00Z") {
        Ok(dt) => println!("Parsed UTC: {}", dt),
        Err(e) => println!("Error: {}", e),
    }

    // 2. Parse custom formats
    println!("\n--- 2. Parse Custom Formats ---");
    match parse_date_only("2024-01-15") {
        Ok(date) => println!("Parsed date: {}", date),
        Err(e) => println!("Error: {}", e),
    }

    match parse_time_only("14:30:00") {
        Ok(time) => println!("Parsed time: {}", time),
        Err(e) => println!("Error: {}", e),
    }

    // 3. Parse common formats
    println!("\n--- 3. Parse Common Formats ---");
    match parse_us_date("01/15/2024") {
        Ok(date) => println!("US date: {}", date),
        Err(e) => println!("Error: {}", e),
    }

    match parse_eu_date("15/01/2024") {
        Ok(date) => println!("EU date: {}", date),
        Err(e) => println!("Error: {}", e),
    }

    // 4. Parse timestamps
    println!("\n--- 4. Parse Timestamps ---");
    match parse_timestamp_seconds(1705317600) {
        Ok(dt) => println!("Timestamp 1705317600: {}", dt),
        Err(e) => println!("Error: {}", e),
    }

    // 5. Parse with custom format
    println!("\n--- 5. Parse Custom Format ---");
    match parse_custom_format("January 15, 2024 10:30 AM", "%B %d, %Y %I:%M %p") {
        Ok(dt) => println!("Custom format: {}", dt),
        Err(e) => println!("Error: {}", e),
    }

    // 6. Flexible parsing
    println!("\n--- 6. Flexible Parsing ---");
    let date_str = "01/15/2024";
    match parse_date_flexible(date_str) {
        Some(date) => println!("Flexible parse '{}': {}", date_str, date),
        None => println!("Could not parse '{}'", date_str),
    }

    // 7. Parse RFC formats
    println!("\n--- 7. Parse RFC Formats ---");
    let rfc2822_str = "Mon, 15 Jan 2024 10:30:00 +0000";
    match parse_rfc2822(rfc2822_str) {
        Ok(dt) => println!("RFC 2822: {}", dt),
        Err(e) => println!("Error: {}", e),
    }

    // 8. Relative time parsing
    println!("\n--- 8. Parse Relative Time ---");
    match parse_days_ago("5 days ago") {
        Some(dt) => println!("5 days ago: {}", dt),
        None => println!("Could not parse"),
    }

    // 9. Extract components
    println!("\n--- 9. Extract Components ---");
    let text = "The event is on 2024-01-15";
    match extract_year(text) {
        Some(year) => println!("Extracted year: {}", year),
        None => println!("Could not extract year"),
    }

    // 10. Batch parsing
    println!("\n--- 10. Batch Parsing ---");
    let dates = vec![
        "2024-01-15".to_string(),
        "2024-02-20".to_string(),
        "2024-03-25".to_string(),
    ];
    let parsed = parse_multiple_dates(&dates, "%Y-%m-%d");
    println!("Parsed {} out of {} dates",
        parsed.iter().filter(|r| r.is_ok()).count(),
        dates.len()
    );

    println!("\n=== All Time Parsing Examples Completed ===");
}