Skip to content

Instantly share code, notes, and snippets.

@backslash-f
Last active June 27, 2020 06:47
Show Gist options
  • Save backslash-f/f5aad05cf69ffac4bff7ec42e7ecc55f to your computer and use it in GitHub Desktop.
Save backslash-f/f5aad05cf69ffac4bff7ec42e7ecc55f to your computer and use it in GitHub Desktop.

Revisions

  1. Fernando Fernandes revised this gist Jun 27, 2020. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion Formatters.swift
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,7 @@
    // See "Displaying Human-Friendly Content" at https://developer.apple.com/documentation/foundation/formatter/displaying_human-friendly_content
    /*
    See "Displaying Human-Friendly Content"
    https://developer.apple.com/documentation/foundation/formatter/displaying_human-friendly_content
    */

    import Foundation
    /*:
  2. Fernando Fernandes created this gist Jun 27, 2020.
    244 changes: 244 additions & 0 deletions Formatters.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,244 @@
    // See "Displaying Human-Friendly Content" at https://developer.apple.com/documentation/foundation/formatter/displaying_human-friendly_content

    import Foundation
    /*:
    ## Number Formatter
    Provides localized representations of units and measurements.
    */

    let numberFormatter = NumberFormatter()

    let money = NSNumber(value: 5)
    numberFormatter.locale = Locale(identifier: "en_US")
    numberFormatter.numberStyle = .currency
    numberFormatter.string(from: money)

    let percentage = NSNumber(value: 0.05)
    numberFormatter.numberStyle = .percent
    numberFormatter.string(from: percentage)

    let spell = NSNumber(value: 345)
    numberFormatter.numberStyle = .spellOut
    numberFormatter.string(from: spell)

    let cents = NSNumber(value: 1.2345)
    numberFormatter.maximumFractionDigits = 2 // Limits fraction to two decimal places
    numberFormatter.locale = Locale.autoupdatingCurrent // Sets locale based on user's current location
    numberFormatter.numberStyle = .currency
    numberFormatter.string(from: cents)

    /*:
    ## Person Name Components Formatter
    Provides localized representations of the components of a person’s name.
    */

    let pncf = PersonNameComponentsFormatter()
    var person = PersonNameComponents()
    person.namePrefix = "Miss"
    person.givenName = "Jane"
    person.middleName = "Doe"
    person.familyName = "Smith"

    // Get string from Person Name Components
    pncf.style = .short
    pncf.string(from: person)

    pncf.style = .medium // Same as .default
    pncf.string(from: person)

    pncf.style = .long
    pncf.string(from: person)

    pncf.style = .default
    pncf.string(from: person)

    // Get name components from string
    let jane: PersonNameComponents = pncf.personNameComponents(from: "Jane Doe Smith")!
    jane.givenName
    jane.familyName

    /*:
    ## Date Formatter
    Converts between dates and their textual representations.
    */

    let paymentDate = Calendar.current.date(byAdding: DateComponents(day: 15), to: Date())! // 15 days from now
    let dateFormatter = DateFormatter()

    // Generate string representations from different locales and date styles
    dateFormatter.locale = Locale(identifier: "en_US") // Change locale to US
    dateFormatter.dateStyle = .short
    dateFormatter.string(from: paymentDate) // Prints in US date format

    dateFormatter.locale = Locale(identifier: "fr_FR") // Change locale to French for France
    dateFormatter.dateStyle = .medium
    dateFormatter.string(from: paymentDate) // Prints in French date format

    dateFormatter.locale = Locale(identifier: "ja_JP") // Change locale to Japanese for Japan
    dateFormatter.setLocalizedDateFormatFromTemplate("MMM d") // Define data format using template
    dateFormatter.string(from: paymentDate) // Equivalent of "MMM d" in Japanese due to locale

    // Generate Date from string representation
    dateFormatter.dateFormat = "yyyy-MM-dd"
    dateFormatter.date(from: "1984-01-24")

    /*:
    ## Date Components Formatter
    Creates string representations of quantities of time.
    */

    var dcf = DateComponentsFormatter()

    dcf.unitsStyle = .full
    dcf.includesApproximationPhrase = true // about...
    dcf.includesTimeRemainingPhrase = true // ...remaining
    dcf.allowedUnits = [.minute]

    // Use the configured formatter to generate the string.
    dcf.string(from: 300.0)

    // DateComponentsFormatter configuration
    var calendar = Calendar.current
    dcf.calendar = calendar // Set formatter to Gregorian calendar.
    dcf.allowedUnits = [.minute, .hour]

    // DateComponentsFormatter unit styles
    dcf.unitsStyle = .abbreviated
    dcf.string(from: 250.0)

    dcf.unitsStyle = .brief
    dcf.string(from: 250.0)

    dcf.unitsStyle = .positional
    dcf.string(from: 250.0)

    dcf.unitsStyle = .short
    dcf.string(from: 250.0)

    dcf.unitsStyle = .full
    dcf.string(from: 250.0)

    /*:
    ## Date Interval Formatter
    Creates string representations of time intervals.
    */

    let start = Date() // Current date
    let end = Calendar.current.date(byAdding: DateComponents(day: 10), to: Date())! // 10 days from current date
    let interval = DateInterval(start: start, end: end)

    let dif = DateIntervalFormatter()

    // Short date and time style
    dif.dateStyle = .short
    dif.timeStyle = .short
    dif.string(from: interval)

    // Medium date and time style
    dif.dateStyle = .medium
    dif.timeStyle = .medium
    dif.string(from: interval)

    // Long date and time style
    dif.dateStyle = .long
    dif.timeStyle = .long
    dif.string(from: interval)

    // Only time of day
    dif.dateStyle = .none
    dif.timeStyle = .short
    dif.string(from: interval)

    dif.string(from: start, to: end)
    /*:
    ## ISO8601 Date Formatter
    Converts between dates and their ISO 8601 string representations.
    */

    let isof = ISO8601DateFormatter()
    let date = Date(timeIntervalSince1970: 443_826_000)

    // Configuration
    isof.timeZone = TimeZone.current

    // Get ISO 8601 string representation from Date
    isof.string(from: date)

    // Get Date from ISO 8601 formatted strings
    isof.formatOptions = [.withInternetDateTime]
    isof.date(from: "1984-01-24T21:00:00Z") // String format: yyyy-mm-dd'T'hh:mm:ss'Z'

    isof.formatOptions = [.withFullDate]
    isof.date(from: "2000-09-16") // String format: yyyy-mm-dd

    /*:
    ## Byte Count Formatter
    Converts a byte count value into a localized description that is formatted with the appropriate byte modifier (KB, MB, GB, etc.).
    */

    let bcf = ByteCountFormatter()
    var bytes: Int64 = Int64(123_456_789)
    bcf.includesUnit = true
    bcf.includesActualByteCount = true

    // Changing units
    bcf.allowedUnits = .useKB
    bcf.string(fromByteCount: bytes)

    bcf.allowedUnits = .useMB
    bcf.string(fromByteCount: bytes)

    bcf.allowedUnits = .useGB
    bcf.string(fromByteCount: bytes)

    // Changing count styles
    bytes = Int64(100_000)
    bcf.allowedUnits = .useAll // Determines best unit to use based on number of bytes

    bcf.countStyle = .binary // 1024 bytes converts to 1 KB
    bcf.string(fromByteCount: bytes)

    bcf.countStyle = .decimal // 1000 bytes converts to 1 KB
    bcf.string(fromByteCount: bytes)

    bcf.countStyle = .file // File byte counts (decimal style in macOS)
    bcf.string(fromByteCount: bytes)

    bcf.countStyle = .memory // Memory byte counts (binary style in macOS)
    bcf.string(fromByteCount: bytes)

    /*:
    ## Measurement Formatter
    Provides localized representations of units and measurements.
    */

    let distanceInMiles = Measurement(value: 5373, unit: UnitLength.miles)
    let lengthInFeet = Measurement(value: 1000.0, unit: UnitLength.yards)
    let measurementFormatter = MeasurementFormatter()

    // Changing unit styles
    measurementFormatter.unitStyle = .short
    measurementFormatter.string(from: distanceInMiles)

    measurementFormatter.unitStyle = .medium // Defaults to medium if not set
    measurementFormatter.string(from: distanceInMiles)

    measurementFormatter.unitStyle = .long
    measurementFormatter.string(from: distanceInMiles)

    // Changing locales
    measurementFormatter.locale = Locale(identifier: "en_US") // Set locale to English for U.S.
    measurementFormatter.string(from: distanceInMiles)

    measurementFormatter.locale = Locale(identifier: "es_MX") // Set locale to Spanish for Mexico
    measurementFormatter.string(from: distanceInMiles)

    measurementFormatter.locale = Locale(identifier: "fr_FR") // Set locale to French for France
    measurementFormatter.string(from: distanceInMiles)

    // Formatter supports right to left locales
    measurementFormatter.locale = Locale(identifier: "ar_SA") // Set locale to Arabic for Saudi Arabia
    measurementFormatter.string(from: distanceInMiles) // Prints right to left

    measurementFormatter.locale = Locale(identifier: "he_IL") // Set locale to Hebrew for Israel
    measurementFormatter.string(from: distanceInMiles) // Prints right to left