Ejemplos de Fecha y Hora macOS Swift

Ejemplos de fecha y hora macOS Swift incluyendo obtención de hora actual, formateo y análisis de fechas

💻 Obtener Hora Actual swift

🟢 simple ⭐⭐

Obtener la hora actual del sistema usando Date, Calendar y NSDate components

⏱️ 20 min 🏷️ swift, macos, datetime, time
Prerequisites: Basic Swift knowledge, Foundation framework
// macOS Swift Get Current Time Examples
// Using Foundation framework

import Foundation

// 1. Basic Current Time
class BasicCurrentTime {

    static func getCurrentTime() {
        print("\n--- Basic Current Time ---")

        // Current date and time
        let now = Date()
        print("Current date: \(now)")

        // Print in different formats
        print("Description: \(now.description)")

        // Get time since reference date (Jan 1, 2001)
        let timeIntervalSinceReferenceDate = now.timeIntervalSinceReferenceDate
        print("Time since reference date (2001): \(timeIntervalSinceReferenceDate) seconds")

        // Get time since 1970 (Unix timestamp)
        let timeIntervalSince1970 = now.timeIntervalSince1970
        print("Unix timestamp: \(timeIntervalSince1970)")

        // Tomorrow and yesterday
        let tomorrow = Date().addingTimeInterval(86400)
        let yesterday = Date().addingTimeInterval(-86400)
        print("Tomorrow: \(tomorrow)")
        print("Yesterday: \(yesterday)")
    }
}

// 2. Date Components
class DateComponentsExample {

    static func getDateComponents() {
        print("\n--- Date Components ---")

        let now = Date()
        let calendar = Calendar.current

        // Extract components
        let components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)

        print("Year: \(components.year ?? 0)")
        print("Month: \(components.month ?? 0)")
        print("Day: \(components.day ?? 0)")
        print("Hour: \(components.hour ?? 0)")
        print("Minute: \(components.minute ?? 0)")
        print("Second: \(components.second ?? 0)")

        // Get individual components
        let year = calendar.component(.year, from: now)
        let month = calendar.component(.month, from: now)
        let day = calendar.component(.day, from: now)
        let weekday = calendar.component(.weekday, from: now)
        let weekOfYear = calendar.component(.weekOfYear, from: now)

        print("\nIndividual components:")
        print("  Year: \(year)")
        print("  Month: \(month)")
        print("  Day: \(day)")
        print("  Weekday: \(weekday) (1=Sunday, 7=Saturday)")
        print("  Week of year: \(weekOfYear)")

        // Get era and quarter
        let era = calendar.component(.era, from: now)
        let quarter = calendar.component(.quarter, from: now)
        print("  Era: \(era)")
        print("  Quarter: \(quarter)")
    }
}

// 3. Time Zone Information
class TimeZoneExample {

    static void getTimeZoneInfo() {
        print("\n--- Time Zone Information ---")

        let now = Date()

        // Local time zone
        let localTimeZone = TimeZone.current
        print("Local time zone: \(localTimeZone.abbreviation() ?? "")")
        print("Local time zone name: \(localTimeZone.identifier)")
        print("Seconds from GMT: \(localTimeZone.secondsFromGMT())")

        // Get current time in different time zones
        let utcTimeZone = TimeZone(identifier: "UTC")!
        var utcCalendar = Calendar.current
        utcCalendar.timeZone = utcTimeZone

        let utcComponents = utcCalendar.dateComponents([.hour, .minute], from: now)
        print("\nUTC time: \(String(format: "%02d:%02d", utcComponents.hour ?? 0, utcComponents.minute ?? 0))")

        // New York time
        if let nyTimeZone = TimeZone(identifier: "America/New_York") {
            var nyCalendar = Calendar.current
            nyCalendar.timeZone = nyTimeZone

            let nyComponents = nyCalendar.dateComponents([.hour, .minute], from: now)
            print("New York time: \(String(format: "%02d:%02d", nyComponents.hour ?? 0, nyComponents.minute ?? 0))")
        }

        // Tokyo time
        if let tokyoTimeZone = TimeZone(identifier: "Asia/Tokyo") {
            var tokyoCalendar = Calendar.current
            tokyoCalendar.timeZone = tokyoTimeZone

            let tokyoComponents = tokyoCalendar.dateComponents([.hour, .minute], from: now)
            print("Tokyo time: \(String(format: "%02d:%02d", tokyoComponents.hour ?? 0, tokyoComponents.minute ?? 0))")
        }

        // List all available time zone abbreviations
        print("\nCommon time zones:")
        let timeZoneIDs = [
            "UTC",
            "America/New_York",
            "America/Los_Angeles",
            "Europe/London",
            "Europe/Paris",
            "Asia/Tokyo",
            "Asia/Shanghai",
            "Australia/Sydney"
        ]

        for id in timeZoneIDs {
            if let tz = TimeZone(identifier: id) {
                print("  \(id): \(tz.abbreviation() ?? "")")
            }
        }
    }
}

// 4. Calendar Information
class CalendarInfo {

    static void getCalendarInfo() {
        print("\n--- Calendar Information ---")

        let calendar = Calendar.current
        let now = Date()

        // Calendar identifier
        print("Calendar identifier: \(calendar.identifier)")

        // Locale
        print("Locale: \(calendar.locale?.identifier ?? "default")")

        // First weekday
        print("First weekday: \(calendar.firstWeekday)")
        print("  (1=Sunday, 2=Monday, etc.)")

        // Minimum days in first week
        print("Minimum days in first week: \(calendar.minimumDaysInFirstWeek)")

        // Time zone
        print("Time zone: \(calendar.timeZone.abbreviation() ?? "")")

        // Date range
        print("\nDate range:")
        print("  Earliest date: \(calendar.earliestDate ?? Date.distantPast)")

        // Number of days in month
        let range = calendar.range(of: .day, in: .month, for: now)
        print("  Days in current month: \(range?.count ?? 0)")

        // Is date in weekend
        let isWeekend = calendar.isDateInWeekend(now)
        print("  Is today weekend: \(isWeekend)")

        // Is today in current week
        let isToday = calendar.isDateInToday(now)
        print("  Is today: \(isToday)")

        // Is tomorrow in current week
        let tomorrow = now.addingTimeInterval(86400)
        let isTomorrow = calendar.isDateInTomorrow(tomorrow)
        print("  Is tomorrow: \(isTomorrow)")
    }
}

// 5. High-Resolution Timing
class HighResolutionTiming {

    static void getHighResolutionTime() {
        print("\n--- High-Resolution Timing ---")

        // CFAbsoluteTime (similar to CACurrentMediaTime)
        let startTime = CFAbsoluteTimeGetCurrent()

        // Simulate some work
        Thread.sleep(forTimeInterval: 0.1)

        let endTime = CFAbsoluteTimeGetCurrent()
        let elapsed = endTime - startTime

        print("Elapsed time: \(elapsed) seconds")
        print("Elapsed time: \(elapsed * 1000) milliseconds")

        // Process info time
        let processInfo = ProcessInfo.processInfo
        print("\nProcess info:")
        print("  System uptime: \(processInfo.systemUptime) seconds")
        print("  Process start time: \(processInfo.processInfo)")

        // Get time since boot (macOS specific)
        var bootTime = timeval()
        var mib: [Int32] = [CTL_KERN, KERN_BOOTTIME]
        var size = MemoryLayout<timeval>.stride

        sysctl(&mib, 2, &bootTime, &size, nil, 0)
        let bootDate = Date(timeIntervalSince1970: Double(bootTime.tv_sec) + Double(bootTime.tv_usec) / 1_000_000)
        let timeSinceBoot = Date().timeIntervalSince(bootDate)

        print("  Time since boot: \(timeSinceBoot) seconds")

        // Monotonic clock (always increases)
        let monotonicTime = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)
        print("  Monotonic nanoseconds: \(monotonicTime)")
    }
}

// 6. Date Comparison
class DateComparison {

    static void compareDates() {
        print("\n--- Date Comparison ---")

        let now = Date()
        let past = now.addingTimeInterval(-3600) // 1 hour ago
        let future = now.addingTimeInterval(3600) // 1 hour in future

        // Compare dates
        print("Now vs Past: \(now.compare(past).rawValue)")
        print("  (1 = descending, -1 = ascending)")

        // Check order
        print("Now is after past: \(now > past)")
        print("Now is before future: \(now < future)")

        // Time interval between dates
        let interval = future.timeIntervalSince(now)
        print("Time between now and future: \(interval) seconds")

        // Compare without time component
        let calendar = Calendar.current
        let sameDay = calendar.isDate(now, inSameDayAs: past)
        print("Is now in same day as past: \(sameDay)")

        // Compare specific components
        let components = calendar.dateComponents([.hour, .minute], from: now, to: future)
        print("Hours between: \(components.hour ?? 0)")
        print("Minutes between: \(components.minute ?? 0)")
    }
}

// 7. Relative Time
class RelativeTime {

    static void getRelativeTime() {
        print("\n--- Relative Time ---")

        let now = Date()
        let calendar = Calendar.current

        // Start of today
        let startOfDay = calendar.startOfDay(for: now)
        print("Start of today: \(startOfDay)")

        // Start of week
        let startOfWeek = calendar.dateInterval(of: .weekOfYear, for: now)?.start
        print("Start of week: \(startOfWeek ?? now)")

        // Start of month
        let startOfMonth = calendar.dateInterval(of: .month, for: now)?.start
        print("Start of month: \(startOfMonth ?? now)")

        // Start of year
        let startOfYear = calendar.dateInterval(of: .year, for: now)?.start
        print("Start of year: \(startOfYear ?? now)")

        // End of day
        var components = calendar.dateComponents([.year, .month, .day], from: now)
        components.day! += 1
        let endOfDay = calendar.date(from: components)?.addingTimeInterval(-1)
        print("End of today: \(endOfDay ?? now)")

        // Midday
        var middayComponents = calendar.dateComponents([.year, .month, .day], from: now)
        middayComponents.hour = 12
        middayComponents.minute = 0
        middayComponents.second = 0
        let midday = calendar.date(from: middayComponents)
        print("Midday today: \(midday ?? now)")

        // Days remaining in year
        if let endOfYear = calendar.dateInterval(of: .year, for: now)?.end {
            let daysRemaining = calendar.dateComponents([.day], from: now, to: endOfYear).day
            print("Days remaining in year: \(daysRemaining ?? 0)")
        }
    }
}

// 8. Date Arithmetic
class DateArithmetic {

    static void performDateArithmetic() {
        print("\n--- Date Arithmetic ---")

        let now = Date()
        let calendar = Calendar.current

        // Add days
        if let nextWeek = calendar.date(byAdding: .day, value: 7, to: now) {
            print("One week from now: \(nextWeek)")
        }

        // Add months
        if let nextMonth = calendar.date(byAdding: .month, value: 1, to: now) {
            print("One month from now: \(nextMonth)")
        }

        // Add years
        if let nextYear = calendar.date(byAdding: .year, value: 1, to: now) {
            print("One year from now: \(nextYear)")
        }

        // Subtract time
        let past = calendar.date(byAdding: .hour, value: -24, to: now)
        print("24 hours ago: \(past ?? now)")

        // Add multiple components
        var components = DateComponents()
        components.day = 1
        components.hour = 2
        components.minute = 30

        if let futureDate = calendar.date(byAdding: components, to: now) {
            print("1 day, 2 hours, 30 minutes from now: \(futureDate)")
        }

        // Get next weekday
        if let nextMonday = calendar.nextDate(after: now, matching: DateComponents(weekday: 2), matchingPolicy: .nextTime) {
            print("Next Monday: \(nextMonday)")
        }

        // Nth weekday
        if let thirdFriday = calendar.date(bySetting: .day, value: 15, of: now),
           let adjusted = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: adjusted) {
            print("15th of current month: \(adjusted)")
        }
    }
}

// 9. System Time Information
class SystemTimeInfo {

    static void getSystemTimeInfo() {
        print("\n--- System Time Information ---")

        let processInfo = ProcessInfo.processInfo

        // System uptime
        print("System uptime: \(processInfo.systemUptime) seconds")
        print("System uptime: \(processInfo.systemUptime / 3600) hours")

        // Host time zone
        let hostTimeZone = TimeZone.current
        print("Host time zone: \(hostTimeZone.identifier)")
        print("Host time zone abbreviation: \(hostTimeZone.abbreviation() ?? "")")
        print("Host time zone seconds from GMT: \(hostTimeZone.secondsFromGMT())")

        // Daylight saving time
        print("Is daylight saving time: \(hostTimeZone.isDaylightSavingTime(for: Date()))")

        // Next daylight saving time transition
        if let nextDST = hostTimeZone.nextDaylightSavingTimeTransition(after: Date()) {
            print("Next DST transition: \(nextDST)")
        }

        // Localized date
        let formatter = DateFormatter()
        formatter.dateStyle = .full
        formatter.timeStyle = .full
        print("Localized date/time: \(formatter.string(from: Date()))")
    }
}

// 10. Performance Measurement
class PerformanceMeasurement {

    static void measurePerformance() {
        print("\n--- Performance Measurement ---")

        // Measure execution time with Date
        let startDate = Date()

        // Simulate work
        var sum = 0
        for i in 1...1000000 {
            sum += i
        }

        let endDate = Date()
        let executionTime = endDate.timeIntervalSince(startDate)

        print("Sum: \(sum)")
        print("Execution time (Date): \(executionTime) seconds")
        print("Execution time: \(executionTime * 1000) milliseconds")

        // Measure with CFAbsoluteTime
        let start = CFAbsoluteTimeGetCurrent()

        // Simulate work
        Thread.sleep(forTimeInterval: 0.05)

        let end = CFAbsoluteTimeGetCurrent()
        let elapsed = end - start

        print("\nElapsed time (CFAbsoluteTime): \(elapsed) seconds")

        // Use DispatchTime for async operations
        let dispatchStart = DispatchTime.now()

        DispatchQueue.global().async {
            // Do work
            Thread.sleep(forTimeInterval: 0.01)

            let dispatchEnd = DispatchTime.now()
            let nanoTime = dispatchEnd.uptimeNanoseconds - dispatchStart.uptimeNanoseconds
            let timeInterval = Double(nanoTime) / 1_000_000_000

            print("Dispatch time: \(timeInterval) seconds")
        }

        Thread.sleep(forTimeInterval: 0.1)
    }
}

// Main demonstration
func demonstrateGetCurrentTime() {
    print("=== macOS Swift Get Current Time Examples ===")

    BasicCurrentTime.getCurrentTime()
    DateComponentsExample.getDateComponents()
    TimeZoneExample.getTimeZoneInfo()
    CalendarInfo.getCalendarInfo()
    HighResolutionTiming.getHighResolutionTime()
    DateComparison.compareDates()
    RelativeTime.getRelativeTime()
    DateArithmetic.performDateArithmetic()
    SystemTimeInfo.getSystemTimeInfo()
    PerformanceMeasurement.measurePerformance()

    print("\n=== All Get Current Time Examples Completed ===")
}

// Run demonstration
demonstrateGetCurrentTime()

💻 Formateo de Hora swift

🟡 intermediate ⭐⭐⭐

Formatear fechas y horas usando DateFormatter con varios estilos y formatos personalizados

⏱️ 25 min 🏷️ swift, macos, datetime, formatting
Prerequisites: Intermediate Swift, DateFormatter, Locale
// macOS Swift Time Formatting Examples
// Using Foundation framework

import Foundation

// 1. Predefined Styles
class PredefinedStyles {

    static void demonstrateStyles() {
        print("\n--- Predefined Date Styles ---")

        let now = Date()

        // Date styles
        let dateFormatter = DateFormatter()

        print("Date styles:")
        dateFormatter.dateStyle = .short
        print("  Short: \(dateFormatter.string(from: now))")

        dateFormatter.dateStyle = .medium
        print("  Medium: \(dateFormatter.string(from: now))")

        dateFormatter.dateStyle = .long
        print("  Long: \(dateFormatter.string(from: now))")

        dateFormatter.dateStyle = .full
        print("  Full: \(dateFormatter.string(from: now))")

        print("\nTime styles:")
        dateFormatter.dateStyle = .none

        dateFormatter.timeStyle = .short
        print("  Short: \(dateFormatter.string(from: now))")

        dateFormatter.timeStyle = .medium
        print("  Medium: \(dateFormatter.string(from: now))")

        dateFormatter.timeStyle = .long
        print("  Long: \(dateFormatter.string(from: now))")

        dateFormatter.timeStyle = .full
        print("  Full: \(dateFormatter.string(from: now))")

        print("\nCombined styles:")
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .short
        print("  Medium/Short: \(dateFormatter.string(from: now))")

        dateFormatter.dateStyle = .full
        dateFormatter.timeStyle = .full
        print("  Full/Full: \(dateFormatter.string(from: now))")
    }
}

// 2. Custom Date Formats
class CustomFormats {

    static void demonstrateCustomFormats() {
        print("\n--- Custom Date Formats ---")

        let now = Date()
        let formatter = DateFormatter()

        // Custom format strings
        let formats: [(String, String)] = [
            ("yyyy-MM-dd", "ISO Date"),
            ("MM/dd/yyyy", "US Date"),
            ("dd/MM/yyyy", "European Date"),
            ("dd-MM-yyyy", "Short Date"),
            ("MMM d, yyyy", "With month name"),
            ("MMMM d, yyyy", "Full month name"),
            ("EEE, MMM d, yyyy", "With weekday"),
            ("EEEE, MMMM d, yyyy", "Full weekday name"),
            ("yyyy-MM-dd HH:mm:ss", "Date and time"),
            ("h:mm a", "Time with AM/PM"),
            ("HH:mm:ss", "24-hour time"),
            ("yyyy-MM-dd'T'HH:mm:ssZ", "ISO 8601"),
            ("MMMM d, yyyy 'at' h:mm a", "Friendly format")
        ]

        for (format, description) in formats {
            formatter.dateFormat = format
            print("\n\(description):")
            print("  Format: \(format)")
            print("  Result: \(formatter.string(from: now))")
        }
    }
}

// 3. Locale-Aware Formatting
class LocaleFormatting {

    static void demonstrateLocaleFormatting() {
        print("\n--- Locale-Aware Formatting ---")

        let now = Date()
        let locales = [
            "en_US",
            "en_GB",
            "fr_FR",
            "de_DE",
            "es_ES",
            "ja_JP",
            "zh_CN",
            "ru_RU",
            "ar_SA"
        ]

        print("Date formatted for different locales:")
        for localeId in locales {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: localeId)
            formatter.dateStyle = .long
            formatter.timeStyle = .medium

            print("  \(localeId): \(formatter.string(from: now))")
        }

        print("\nTime formatted for different locales:")
        for localeId in locales {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: localeId)
            formatter.timeStyle = .short

            print("  \(localeId): \(formatter.string(from: now))")
        }
    }
}

// 4. Relative Date Formatting
class RelativeFormatting {

    static void demonstrateRelativeFormatting() {
        print("\n--- Relative Date Formatting ---")

        let formatter = RelativeDateTimeFormatter()
        let now = Date()

        let dates = [
            now,
            now.addingTimeInterval(-60),
            now.addingTimeInterval(-3600),
            now.addingTimeInterval(-86400),
            now.addingTimeInterval(-86400 * 2),
            now.addingTimeInterval(-86400 * 7),
            now.addingTimeInterval(60),
            now.addingTimeInterval(3600),
            now.addingTimeInterval(86400),
            now.addingTimeInterval(86400 * 7)
        ]

        print("Relative date strings:")
        for date in dates {
            let relativeString = formatter.localizedString(for: date, relativeTo: now)
            let timeDiff = date.timeIntervalSince(now)

            if timeDiff == 0 {
                print("  Now: \(relativeString)")
            } else {
                print("  \(Int(timeDiff))s: \(relativeString)")
            }
        }

        // Different units
        print("\nDifferent units:")
        formatter.unitsStyle = .full
        print("  Full: \(formatter.localizedString(for: now.addingTimeInterval(-3600), relativeTo: now))")

        formatter.unitsStyle = .short
        print("  Short: \(formatter.localizedString(for: now.addingTimeInterval(-3600), relativeTo: now))")

        formatter.unitsStyle = .spellOut
        print("  Spell out: \(formatter.localizedString(for: now.addingTimeInterval(-3600), relativeTo: now))")
    }
}

// 5. Time Zone Formatting
class TimeZoneFormatting {

    static void demonstrateTimeZoneFormatting() {
        print("\n--- Time Zone Formatting ---")

        let now = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"

        let timeZones = [
            "UTC",
            "America/New_York",
            "America/Los_Angeles",
            "Europe/London",
            "Europe/Paris",
            "Asia/Tokyo",
            "Asia/Shanghai",
            "Australia/Sydney"
        ]

        print("Current time in different time zones:")
        for tzId in timeZones {
            if let timeZone = TimeZone(identifier: tzId) {
                formatter.timeZone = timeZone
                print("  \(tzId): \(formatter.string(from: now))")
            }
        }

        // Include time zone name
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
        formatter.timeZone = TimeZone.current
        print("\nLocal with zone: \(formatter.string(from: now))")
    }
}

// 6. Named Date Formatting
class NamedDateFormatting {

    static void demonstrateNamedFormatting() {
        print("\n--- Named Date Formatting ---")

        let formatter = DateFormatter()
        let now = Date()

        // Today
        formatter.doesRelativeDateFormatting = true
        formatter.dateStyle = .medium
        formatter.timeStyle = .none

        print("Today: \(formatter.string(from: now))")

        // Tomorrow
        let tomorrow = now.addingTimeInterval(86400)
        print("Tomorrow: \(formatter.string(from: tomorrow))")

        // Yesterday
        let yesterday = now.addingTimeInterval(-86400)
        print("Yesterday: \(formatter.string(from: yesterday))")

        // Next week
        let nextWeek = now.addingTimeInterval(86400 * 7)
        print("Next week: \(formatter.string(from: nextWeek))")
    }
}

// 7. ISO 8601 Formatting
class ISO8601Formatting {

    static void demonstrateISO8601() {
        print("\n--- ISO 8601 Formatting ---")

        let now = Date()

        // Using ISO8601DateFormatter
        let isoFormatter = ISO8601DateFormatter()

        print("ISO 8601 formats:")

        // With time zone
        isoFormatter.formatOptions = [
            .withInternetDateTime,
            .withFractionalSeconds
        ]
        let withTimeZone = isoFormatter.string(from: now)
        print("  With time zone: \(withTimeZone)")

        // Without time zone
        isoFormatter.formatOptions = [
            .withYear,
            .withMonth,
            .withDay,
            .withTime,
            .withFractionalSeconds
        ]
        let withoutTimeZone = isoFormatter.string(from: now)
        print("  Without time zone: \(withoutTimeZone)")

        // Date only
        isoFormatter.formatOptions = [.withYear, .withMonth, .withDay]
        let dateOnly = isoFormatter.string(from: now)
        print("  Date only: \(dateOnly)")

        // Time only
        isoFormatter.formatOptions = [.withTime, .withFractionalSeconds]
        let timeOnly = isoFormatter.string(from: now)
        print("  Time only: \(timeOnly)")

        // Parse ISO 8601
        let isoString = "2024-01-15T10:30:45Z"
        if let parsed = isoFormatter.date(from: isoString) {
            print("\nParsed ISO 8601: \(parsed)")
        }
    }
}

// 8. Custom Date Template
class CustomDateTemplate {

    static void demonstrateCustomTemplates() {
        print("\n--- Custom Date Templates ---")

        let now = Date()
        let formatter = DateFormatter()

        // Using setLocalizedDateFormatFromTemplate
        let templates = [
            "yyyyMMMd",       // Jan 15, 2024
            "yMMMMd",         // January 15, 2024
            "Mdyy",           // 1/15/24
            "EEEE, MMM d, y", // Monday, Jan 15, 2024
            "h:mm a",         // 10:30 AM
            "HH:mm:ss",       // 14:30:45
            "yyyyQQQ",        // 2024 Q1
            "yyyy-Www"        // 2024-W03
        ]

        print("Custom template formats:")
        for template in templates {
            formatter.setLocalizedDateFormatFromTemplate(template)
            print("  Template '\(template)': \(formatter.string(from: now))")
        }
    }
}

// 9. Duration Formatting
class DurationFormatting {

    static void demonstrateDurationFormatting() {
        print("\n--- Duration Formatting ---")

        let formatter = DateComponentsFormatter()

        formatter.unitsStyle = .full

        let durations: [TimeInterval] = [
            60,           // 1 minute
            3600,         // 1 hour
            86400,        // 1 day
            90061,        // 1 day, 1 hour, 1 minute
            2678401,      // 31 days
            59,           // 59 seconds
            3661          // 1 hour, 1 minute
        ]

        print("Duration strings:")
        for duration in durations {
            let formatted = formatter.string(from: duration)
            print("  \(Int(duration))s = \(formatted ?? "N/A")")
        }

        // Different styles
        let sampleDuration: TimeInterval = 9061

        formatter.unitsStyle = .full
        print("\n\(sampleDuration)s - Full: \(formatter.string(from: sampleDuration) ?? "")")

        formatter.unitsStyle = .short
        print("\(sampleDuration)s - Short: \(formatter.string(from: sampleDuration) ?? "")")

        formatter.unitsStyle = .brief
        print("\(sampleDuration)s - Brief: \(formatter.string(from: sampleDuration) ?? "")")

        formatter.unitsStyle = .positional
        print("\(sampleDuration)s - Positional: \(formatter.string(from: sampleDuration) ?? "")")

        // Allowed units
        formatter.allowedUnits = [.hour, .minute]
        formatter.unitsStyle = .full
        print("\(sampleDuration)s - Hours & Minutes only: \(formatter.string(from: sampleDuration) ?? "")")

        formatter.allowedUnits = [.day, .hour, .minute, .second]
        print("\(sampleDuration)s - All units: \(formatter.string(from: sampleDuration) ?? "")")
    }
}

// 10. Pretty Date Formatting
class PrettyDateFormatting {

    static void demonstratePrettyFormatting() {
        print("\n--- Pretty Date Formatting ---")

        let now = Date()
        let calendar = Calendar.current

        // Friendly date format
        func prettyDate(_ date: Date) -> String {
            let formatter = DateFormatter()

            if calendar.isDateInToday(date) {
                formatter.dateFormat = "'Today at' h:mm a"
            } else if calendar.isDateInYesterday(date) {
                formatter.dateFormat = "'Yesterday at' h:mm a"
            } else if calendar.isDateInTomorrow(date) {
                formatter.dateFormat = "'Tomorrow at' h:mm a"
            } else {
                formatter.dateFormat = "MMM d, yyyy 'at' h:mm a"
            }

            return formatter.string(from: date)
        }

        let dates = [
            now,
            now.addingTimeInterval(-86400),
            now.addingTimeInterval(-86400 * 2),
            now.addingTimeInterval(86400),
            now.addingTimeInterval(86400 * 7)
        ]

        print("Pretty date formats:")
        for date in dates {
            print("  \(prettyDate(date))")
        }

        // Social media style (e.g., "2h ago")
        func socialMediaStyle(_ date: Date) -> String {
            let interval = abs(date.timeIntervalSince(now))
            let formatter = DateComponentsFormatter()
            formatter.unitsStyle = .abbreviated
            formatter.maximumUnitCount = 1

            if interval < 60 {
                return "just now"
            } else if interval < 3600 {
                return formatter.string(from: interval) ?? "" + " ago"
            } else {
                return formatter.string(from: interval) ?? "" + " ago"
            }
        }

        print("\nSocial media style:")
        for date in dates {
            print("  \(date): \(socialMediaStyle(date))")
        }
    }
}

// Main demonstration
func demonstrateTimeFormatting() {
    print("=== macOS Swift Time Formatting Examples ===")

    PredefinedStyles.demonstrateStyles()
    CustomFormats.demonstrateCustomFormats()
    LocaleFormatting.demonstrateLocaleFormatting()
    RelativeFormatting.demonstrateRelativeFormatting()
    TimeZoneFormatting.demonstrateTimeZoneFormatting()
    NamedDateFormatting.demonstrateNamedFormatting()
    ISO8601Formatting.demonstrateISO8601()
    CustomDateTemplate.demonstrateCustomTemplates()
    DurationFormatting.demonstrateDurationFormatting()
    PrettyDateFormatting.demonstratePrettyFormatting()

    print("\n=== All Time Formatting Examples Completed ===")
}

// Run demonstration
demonstrateTimeFormatting()

💻 Análisis de Hora swift

🟡 intermediate ⭐⭐⭐

Analizar cadenas de fecha en objetos Date usando varios formatos y estrategias

⏱️ 30 min 🏷️ swift, macos, datetime, parsing
Prerequisites: Intermediate Swift, DateFormatter, String parsing
// macOS Swift Time Parsing Examples
// Using Foundation framework

import Foundation

// 1. Basic Date Parsing
class BasicDateParsing {

    static void demonstrateBasicParsing() {
        print("\n--- Basic Date Parsing ---")

        let formatter = DateFormatter()

        // Parse ISO date
        formatter.dateFormat = "yyyy-MM-dd"
        let isoDate = "2024-01-15"
        if let parsed = formatter.date(from: isoDate) {
            print("Parsed '\(isoDate)': \(parsed)")
        }

        // Parse US date
        formatter.dateFormat = "MM/dd/yyyy"
        let usDate = "01/15/2024"
        if let parsed = formatter.date(from: usDate) {
            print("Parsed '\(usDate)': \(parsed)")
        }

        // Parse European date
        formatter.dateFormat = "dd/MM/yyyy"
        let euDate = "15/01/2024"
        if let parsed = formatter.date(from: euDate) {
            print("Parsed '\(euDate)': \(parsed)")
        }

        // Parse with time
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let withTime = "2024-01-15 14:30:45"
        if let parsed = formatter.date(from: withTime) {
            print("Parsed '\(withTime)': \(parsed)")
        }
    }
}

// 2. ISO 8601 Parsing
class ISO8601Parsing {

    static void demonstrateISO8601Parsing() {
        print("\n--- ISO 8601 Parsing ---")

        let isoFormatter = ISO8601DateFormatter()

        let isoDates = [
            "2024-01-15T10:30:45Z",
            "2024-01-15T10:30:45+00:00",
            "2024-01-15T10:30:45-05:00",
            "2024-01-15T10:30:45.123Z",
            "2024-01-15",
            "2024-01",
            "2024-W03"
        ]

        print("Parsing ISO 8601 dates:")
        for isoString in isoDates {
            if let parsed = isoFormatter.date(from: isoString) {
                print("  '\(isoString)' -> \(parsed)")
            } else {
                print("  '\(isoString)' -> FAILED")
            }
        }

        // Parse with specific options
        isoFormatter.formatOptions = [
            .withInternetDateTime,
            .withFractionalSeconds
        ]

        let strictDate = "2024-01-15T10:30:45.123Z"
        if let parsed = isoFormatter.date(from: strictDate) {
            print("\nStrict parsing: \(parsed)")
        }
    }
}

// 3. Flexible Date Parsing
class FlexibleDateParsing {

    static void demonstrateFlexibleParsing() {
        print("\n--- Flexible Date Parsing ---")

        let dateStrings = [
            "01/15/2024",
            "Jan 15, 2024",
            "January 15, 2024",
            "15 Jan 2024",
            "2024-01-15",
            "01-15-2024"
        ]

        let formats = [
            "MM/dd/yyyy",
            "MMM d, yyyy",
            "MMMM d, yyyy",
            "dd MMM yyyy",
            "yyyy-MM-dd",
            "MM-dd-yyyy"
        ]

        print("Trying multiple formats:")
        for dateString in dateStrings {
            var parsedSuccessfully = false

            for format in formats {
                let formatter = DateFormatter()
                formatter.dateFormat = format

                if let parsed = formatter.date(from: dateString) {
                    print("  '\(dateString)' -> '\(format)' -> \(parsed)")
                    parsedSuccessfully = true
                    break
                }
            }

            if !parsedSuccessfully {
                print("  '\(dateString)' -> FAILED")
            }
        }
    }
}

// 4. Natural Language Parsing
class NaturalLanguageParsing {

    static void demonstrateNaturalParsing() {
        print("\n--- Natural Language Parsing ---")

        // Note: Natural language parsing requires NSDataDetector or external libraries
        let naturalStrings = [
            "Meet me tomorrow at 3pm",
            "The event is on January 15, 2024",
            "Deadline: next Friday",
            "Call in 2 hours",
            "See you in 5 minutes"
        ]

        // Using NSDataDetector
        print("Detecting dates in text:")
        for text in naturalStrings {
            let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)

            if let detector = detector {
                let matches = detector.matches(in: text, range: NSRange(text.startIndex..., in: text))

                if !matches.isEmpty {
                    print("  Text: '\(text)'")
                    for match in matches {
                        if let date = match.date {
                            print("    Found date: \(date)")
                        }
                    }
                }
            }
        }
    }
}

// 5. Parsing with Locale
class LocaleParsing {

    static void demonstrateLocaleParsing() {
        print("\n--- Locale-Aware Parsing ---")

        let dateString = "15/01/2024"
        let locales = ["en_US", "fr_FR", "de_DE", "ja_JP"]

        print("Parsing '\(dateString)' with different locales:")
        for localeId in locales {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: localeId)
            formatter.dateFormat = "dd/MM/yyyy"

            if let parsed = formatter.date(from: dateString) {
                print("  \(localeId): \(parsed)")
            }
        }

        // Month names in different languages
        let monthStrings = [
            ("en_US", "January 15, 2024"),
            ("fr_FR", "15 janvier 2024"),
            ("es_ES", "15 de enero de 2024"),
            ("de_DE", "15. Januar 2024")
        ]

        print("\nParsing month names:")
        for (localeId, dateStr) in monthStrings {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: localeId)

            // Try appropriate format for locale
            if localeId.hasPrefix("en") {
                formatter.dateFormat = "MMMM d, yyyy"
            } else if localeId.hasPrefix("fr") {
                formatter.dateFormat = "d MMMM yyyy"
            } else if localeId.hasPrefix("es") {
                formatter.dateFormat = "d 'de' MMMM 'de' yyyy"
            } else if localeId.hasPrefix("de") {
                formatter.dateFormat = "d. MMMM yyyy"
            }

            if let parsed = formatter.date(from: dateStr) {
                print("  \(localeId): '\(dateStr)' -> \(parsed)")
            }
        }
    }
}

// 6. Time Zone Parsing
class TimeZoneParsing {

    static void demonstrateTimeZoneParsing() {
        print("\n--- Time Zone Parsing ---")

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"

        let datesWithZone = [
            "2024-01-15 10:30:45 +0000",
            "2024-01-15 10:30:45 -0500",
            "2024-01-15 10:30:45 +0800"
        ]

        print("Parsing dates with time zones:")
        for dateStr in datesWithZone {
            if let parsed = formatter.date(from: dateStr) {
                print("  '\(dateStr)' -> \(parsed)")
            }
        }

        // Parse and convert time zones
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone = TimeZone(identifier: "UTC")

        let utcDate = "2024-01-15 10:30:45"
        if let parsed = formatter.date(from: utcDate) {
            print("\nParsed as UTC: \(parsed)")

            // Convert to local time
            let localFormatter = DateFormatter()
            localFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            localFormatter.timeZone = TimeZone.current

            print("As local: \(localFormatter.string(from: parsed))")
        }
    }
}

// 7. Parsing Date Components
class DateComponentsParsing {

    static void demonstrateComponentsParsing() {
        print("\n--- Parsing Date Components ---")

        let calendar = Calendar.current

        // Parse from components
        var components = DateComponents()
        components.year = 2024
        components.month = 1
        components.day = 15
        components.hour = 10
        components.minute = 30
        components.second = 45

        if let date = calendar.date(from: components) {
            print("From components: \(date)")
        }

        // Parse weekday
        var weekdayComponents = DateComponents()
        weekdayComponents.year = 2024
        weekdayComponents.month = 1
        weekdayComponents.weekday = 2 // Monday
        weekdayComponents.weekdayOrdinal = 3 // 3rd Monday

        if let thirdMonday = calendar.date(from: weekdayComponents) {
            print("\n3rd Monday of January 2024: \(thirdMonday)")

            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd"
            print("  Formatted: \(formatter.string(from: thirdMonday))")
        }

        // Parse relative to a date
        let baseDate = Date()
        var relativeComponents = DateComponents()
        relativeComponents.day = 7
        relativeComponents.hour = 3

        if let futureDate = calendar.date(byAdding: relativeComponents, to: baseDate) {
            print("\n7 days and 3 hours from now: \(futureDate)")
        }
    }
}

// 8. Handling Parse Errors
class ParseErrorHandling {

    static void demonstrateErrorHandling() {
        print("\n--- Parse Error Handling ---")

        // Optional parsing
        func safeParse(_ dateString: String, format: String) -> Date? {
            let formatter = DateFormatter()
            formatter.dateFormat = format
            return formatter.date(from: dateString)
        }

        print("Safe parsing:")
        let validDate = safeParse("2024-01-15", format: "yyyy-MM-dd")
        print("  Valid date: \(validDate?.description ?? "nil")")

        let invalidDate = safeParse("invalid", format: "yyyy-MM-dd")
        print("  Invalid date: \(invalidDate?.description ?? "nil")")

        // Strict parsing with length check
        func strictParse(_ dateString: String, format: String) -> Date? {
            let formatter = DateFormatter()
            formatter.dateFormat = format
            formatter.lenient = false

            // Check if parsed date matches original string
            guard let parsed = formatter.date(from: dateString) else {
                return nil
            }

            let reformatted = formatter.string(from: parsed)
            return reformatted == dateString ? parsed : nil
        }

        print("\nStrict parsing:")
        print("  '2024-01-15': \(strictParse("2024-01-15", format: "yyyy-MM-dd")?.description ?? "nil")")
        print("  '2024-2-3': \(strictParse("2024-2-3", format: "yyyy-MM-dd")?.description ?? "nil")")

        // Try multiple formats
        func parseWithFormats(_ dateString: String, formats: [String]) -> Date? {
            for format in formats {
                if let parsed = safeParse(dateString, format: format) {
                    return parsed
                }
            }
            return nil
        }

        print("\nTry multiple formats:")
        let flexibleDate = "01/15/2024"
        let flexibleFormats = ["MM/dd/yyyy", "dd/MM/yyyy", "yyyy-MM-dd"]
        print("  '\(flexibleDate)': \(parseWithFormats(flexibleDate, formats: flexibleFormats) ?? Date())")
    }
}

// 9. Unix Timestamp Parsing
class UnixTimestampParsing {

    static void demonstrateUnixTimestampParsing() {
        print("\n--- Unix Timestamp Parsing ---")

        let timestamps: [TimeInterval] = [
            0,
            1642261200,
            1642261200.123,
            Date().timeIntervalSince1970
        ]

        print("Parsing Unix timestamps:")
        for timestamp in timestamps {
            let date = Date(timeIntervalSince1970: timestamp)
            print("  \(timestamp) -> \(date)")
        }

        // Current timestamp
        let current = Date().timeIntervalSince1970
        print("\nCurrent Unix timestamp: \(current)")

        // Milliseconds (JavaScript style)
        let milliseconds = current * 1000
        print("Current in milliseconds: \(milliseconds)")

        // Parse milliseconds
        let msTimestamp: TimeInterval = 1642261200123
        let dateFromMs = Date(timeIntervalSince1970: msTimestamp / 1000)
        print("\nFrom milliseconds \(msTimestamp): \(dateFromMs)")
    }
}

// 10. Batch Date Parsing
class BatchDateParsing {

    static void demonstrateBatchParsing() {
        print("\n--- Batch Date Parsing ---")

        let dateStrings = [
            "2024-01-15",
            "2024-02-20",
            "2024-03-25",
            "invalid",
            "2024-04-30"
        ]

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"

        // Parse all dates, handling errors
        var parsedDates: [Date] = []
        var failedIndices: [Int] = []

        for (index, dateString) in dateStrings.enumerated() {
            if let date = formatter.date(from: dateString) {
                parsedDates.append(date)
            } else {
                failedIndices.append(index)
            }
        }

        print("Parsed \(parsedDates.count) dates successfully")
        print("Failed at indices: \(failedIndices)")

        // Sort parsed dates
        let sortedDates = parsedDates.sorted()
        print("\nSorted dates:")
        let outputFormatter = DateFormatter()
        outputFormatter.dateFormat = "MMM d, yyyy"
        for date in sortedDates {
            print("  \(outputFormatter.string(from: date))")
        }

        // Parallel parsing with multiple formatters
        func batchParse(_ strings: [String], formats: [String]) -> [(String, Date?)] {
            return strings.map { string in
                for format in formats {
                    let formatter = DateFormatter()
                    formatter.dateFormat = format
                    if let date = formatter.date(from: string) {
                        return (string, date)
                    }
                }
                return (string, nil)
            }
        }

        print("\nBatch parsing with multiple formats:")
        let results = batchParse(dateStrings, formats: ["yyyy-MM-dd", "MM/dd/yyyy", "yyyy/MM/dd"])
        for (string, date) in results {
            print("  '\(string)': \(date?.description ?? "FAILED")")
        }
    }
}

// Main demonstration
func demonstrateTimeParsing() {
    print("=== macOS Swift Time Parsing Examples ===")

    BasicDateParsing.demonstrateBasicParsing()
    ISO8601Parsing.demonstrateISO8601Parsing()
    FlexibleDateParsing.demonstrateFlexibleParsing()
    NaturalLanguageParsing.demonstrateNaturalParsing()
    LocaleParsing.demonstrateLocaleParsing()
    TimeZoneParsing.demonstrateTimeZoneParsing()
    DateComponentsParsing.demonstrateComponentsParsing()
    ParseErrorHandling.demonstrateErrorHandling()
    UnixTimestampParsing.demonstrateUnixTimestampParsing()
    BatchDateParsing.demonstrateBatchParsing()

    print("\n=== All Time Parsing Examples Completed ===")
}

// Run demonstration
demonstrateTimeParsing()