Adjust formatting
This commit is contained in:
parent
66589c6ccb
commit
3d092ab2c2
|
@ -5,6 +5,10 @@
|
|||
|
||||
This version adjusts the library for Xcode 14 and deprecates some things.
|
||||
|
||||
### ✨ New features
|
||||
|
||||
* `DateFormatter+Init` has a new convenience initializer.
|
||||
|
||||
### 💥 Breaking changes
|
||||
|
||||
* Due to conflicting with TagKit, `String+Slugifies` has been removed.
|
||||
|
|
|
@ -23,7 +23,10 @@ public extension Date {
|
|||
second: Int = 0,
|
||||
calendar: Calendar = .current) {
|
||||
let components = DateComponents(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
|
||||
guard let date = calendar.date(from: components) else { return nil }
|
||||
guard let date = calendar.date(from: components) else {
|
||||
assertionFailure("Invalid date")
|
||||
return nil
|
||||
}
|
||||
self = date
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// DateFormatter+Init.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2018-09-05.
|
||||
// Copyright © 2018 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension DateFormatter {
|
||||
|
||||
/**
|
||||
Create a custom date formatter, that uses a custom date
|
||||
format, calendar, locale and time zone.
|
||||
|
||||
- Parameters:
|
||||
- dateStyle: The date style to use.
|
||||
- timeStyle: The time style to use, by default `.none`.
|
||||
- locale: The locale to use, by default `en_US_POSIX`.
|
||||
- calendar: The calendar to use, by default `iso8601`.
|
||||
*/
|
||||
convenience init(
|
||||
dateStyle: DateFormatter.Style,
|
||||
timeStyle: DateFormatter.Style = .none,
|
||||
locale: Locale = Locale(identifier: "en_US_POSIX"),
|
||||
calendar: Calendar = Calendar(identifier: .iso8601)
|
||||
) {
|
||||
self.init()
|
||||
self.dateStyle = dateStyle
|
||||
self.timeStyle = timeStyle
|
||||
self.locale = locale
|
||||
self.calendar = calendar
|
||||
}
|
||||
|
||||
/**
|
||||
Create a custom date formatter, that uses a custom date
|
||||
format, calendar, locale and time zone.
|
||||
|
||||
- Parameters:
|
||||
- dateFormat: The date string format to use.
|
||||
- calendar: The calendar to use, by default `iso8601`.
|
||||
- locale: The locale to use, by default `en_US_POSIX`.
|
||||
- timeZone: The time zone to use, by default `GMT`.
|
||||
*/
|
||||
convenience init(
|
||||
dateFormat: String,
|
||||
calendar: Calendar = Calendar(identifier: .iso8601),
|
||||
locale: Locale = Locale(identifier: "en_US_POSIX"),
|
||||
timeZone: TimeZone? = TimeZone(secondsFromGMT: 0)) {
|
||||
self.init()
|
||||
self.calendar = calendar
|
||||
self.locale = locale
|
||||
self.dateFormat = dateFormat
|
||||
self.timeZone = timeZone
|
||||
}
|
||||
|
||||
/**
|
||||
Create a date formatter using the ISO8601 second format.
|
||||
*/
|
||||
static var iso8601Seconds: DateFormatter {
|
||||
DateFormatter(dateFormat: "yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
}
|
||||
|
||||
/**
|
||||
Create a date formatter using the ISO8601 ms format.
|
||||
*/
|
||||
static var iso8601Milliseconds: DateFormatter {
|
||||
DateFormatter(dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
//
|
||||
// DateFormatters.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2018-09-05.
|
||||
// Copyright © 2020 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension DateFormatter {
|
||||
|
||||
/**
|
||||
Create a custom date formatter, that uses a custom date
|
||||
format, calendar, locale and time zone.
|
||||
*/
|
||||
convenience init(
|
||||
dateFormat: String,
|
||||
calendar: Calendar = Calendar(identifier: .iso8601),
|
||||
locale: Locale = Locale(identifier: "en_US_POSIX"),
|
||||
timeZone: TimeZone? = TimeZone(secondsFromGMT: 0)) {
|
||||
self.init()
|
||||
self.calendar = calendar
|
||||
self.locale = locale
|
||||
self.dateFormat = dateFormat
|
||||
self.timeZone = timeZone
|
||||
}
|
||||
|
||||
/**
|
||||
Create a date formatter using the ISO8601 second format.
|
||||
*/
|
||||
static var iso8601Seconds: DateFormatter {
|
||||
DateFormatter(dateFormat: "yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
}
|
||||
|
||||
/**
|
||||
Create a date formatter using the ISO8601 ms format.
|
||||
*/
|
||||
static var iso8601Milliseconds: DateFormatter {
|
||||
DateFormatter(dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// NumberFormatter+Init.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2022-10-19.
|
||||
// Copyright © 2022 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension NumberFormatter {
|
||||
|
||||
/**
|
||||
Create number formatter with a certain locale and style.
|
||||
|
||||
The initializer will default to US English to make sure
|
||||
that we by default get the default Qapital locale.
|
||||
|
||||
- Parameters:
|
||||
- numberStyle: The number style to use.
|
||||
- fixedDecimals: The number of fixed decimals to use, if any, by default `nil`.
|
||||
- locale: The locale to use, by default `en-US`.
|
||||
*/
|
||||
convenience init(
|
||||
numberStyle: NumberFormatter.Style,
|
||||
fixedDecimals: Int? = nil,
|
||||
locale: Locale = Locale(identifier: "en-US")
|
||||
) {
|
||||
self.init()
|
||||
self.numberStyle = numberStyle
|
||||
if let decimals = fixedDecimals {
|
||||
minimumFractionDigits = decimals
|
||||
maximumFractionDigits = decimals
|
||||
}
|
||||
self.locale = locale
|
||||
}
|
||||
}
|
||||
|
||||
public extension NumberFormatter {
|
||||
|
||||
/**
|
||||
A percent formatter with a fixed number of decimals.
|
||||
*/
|
||||
static func percent(decimals: Int) -> NumberFormatter {
|
||||
NumberFormatter(
|
||||
numberStyle: .percent,
|
||||
fixedDecimals: decimals
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// NumberFormatter+Util.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2022-10-19.
|
||||
// Copyright © 2022 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension NumberFormatter {
|
||||
|
||||
/**
|
||||
Create a string for a double value.
|
||||
*/
|
||||
func string(for value: Double) -> String? {
|
||||
string(for: NSNumber(value: value))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// DateFormatter+InitTests.swift
|
||||
// SwiftKitTests
|
||||
//
|
||||
// Created by Daniel Saidi on 2018-09-05.
|
||||
// Copyright © 2018 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftKit
|
||||
import XCTest
|
||||
|
||||
class DateFormatter_InitTests: XCTestCase {
|
||||
|
||||
func testConvenienceInitializerUsesUsEnglishWithNoTimeByDefault() {
|
||||
let formatter = DateFormatter(dateStyle: .medium)
|
||||
XCTAssertEqual(formatter.locale.identifier, "en_US_POSIX")
|
||||
XCTAssertEqual(formatter.dateStyle, .medium)
|
||||
XCTAssertEqual(formatter.timeStyle, .none)
|
||||
}
|
||||
|
||||
func testConvenienceInstanceGeneratesValidDateStringForMediumDateStyle() {
|
||||
let date = Date(year: 2022, month: 10, day: 19) ?? Date()
|
||||
let formatter = DateFormatter(dateStyle: .medium)
|
||||
let result = formatter.string(from: date)
|
||||
XCTAssertEqual(result, "Oct 19, 2022")
|
||||
}
|
||||
|
||||
func testConvenienceInstanceGeneratesValidDateStringForLongDateStyleAndShortTimeStyle() {
|
||||
let date = Date(year: 2022, month: 10, day: 19) ?? Date()
|
||||
let formatter = DateFormatter(
|
||||
dateStyle: .long,
|
||||
timeStyle: .short
|
||||
)
|
||||
let result = formatter.string(from: date)
|
||||
XCTAssertEqual(result, "October 19, 2022 at 12:00 AM")
|
||||
}
|
||||
|
||||
func testConvenienceInstanceGeneratesValidDateStringForCustomLocale() {
|
||||
let date = Date(year: 2022, month: 10, day: 19) ?? Date()
|
||||
let formatter = DateFormatter(
|
||||
dateStyle: .long,
|
||||
timeStyle: .short,
|
||||
locale: Locale(identifier: "sv-SE")
|
||||
)
|
||||
let result = formatter.string(from: date)
|
||||
XCTAssertEqual(result, "19 oktober 2022 00:00")
|
||||
}
|
||||
|
||||
func testIso8601SecondFormatterIsValid() {
|
||||
let formatter = DateFormatter.iso8601Seconds
|
||||
XCTAssertEqual(formatter.dateFormat, "yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
XCTAssertEqual(formatter.calendar.identifier, .iso8601)
|
||||
XCTAssertEqual(formatter.locale.identifier, "en_US_POSIX")
|
||||
XCTAssertNotNil(formatter.timeZone)
|
||||
}
|
||||
|
||||
func testIso8601MilliSecondFormatterIsValid() {
|
||||
let formatter = DateFormatter.iso8601Milliseconds
|
||||
XCTAssertEqual(formatter.dateFormat, "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
XCTAssertEqual(formatter.calendar.identifier, .iso8601)
|
||||
XCTAssertEqual(formatter.locale.identifier, "en_US_POSIX")
|
||||
XCTAssertNotNil(formatter.timeZone)
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// DateFormattersTests.swift
|
||||
// SwiftKitTests
|
||||
//
|
||||
// Created by Daniel Saidi on 2018-09-05.
|
||||
// Copyright © 2020 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Quick
|
||||
import Nimble
|
||||
import SwiftKit
|
||||
|
||||
class DateFormattersTests: QuickSpec {
|
||||
|
||||
override func spec() {
|
||||
|
||||
describe("iso8601 second formatter") {
|
||||
|
||||
it("is correctly setup") {
|
||||
let formatter = DateFormatter.iso8601Seconds
|
||||
expect(formatter.dateFormat).to(equal("yyyy-MM-dd'T'HH:mm:ssZ"))
|
||||
expect(formatter.calendar.identifier).to(equal(.iso8601))
|
||||
expect(formatter.locale.identifier).to(equal("en_US_POSIX"))
|
||||
expect(formatter.timeZone).toNot(beNil())
|
||||
}
|
||||
}
|
||||
|
||||
describe("iso8601 millisecond formatter") {
|
||||
|
||||
it("is correctly setup") {
|
||||
let formatter = DateFormatter.iso8601Milliseconds
|
||||
expect(formatter.dateFormat).to(equal("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))
|
||||
expect(formatter.calendar.identifier).to(equal(.iso8601))
|
||||
expect(formatter.locale.identifier).to(equal("en_US_POSIX"))
|
||||
expect(formatter.timeZone).toNot(beNil())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// NumberFormatter+InitTests.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2022-10-19.
|
||||
// Copyright © 2012 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftKit
|
||||
import XCTest
|
||||
|
||||
class NumberFormatter_InitTests: XCTestCase {
|
||||
|
||||
func testConvenienceInitializerUsesUsEnglishByDefault() {
|
||||
let formatter = NumberFormatter(numberStyle: .currency)
|
||||
XCTAssertEqual(formatter.locale.identifier, "en-US")
|
||||
XCTAssertEqual(formatter.numberStyle, .currency)
|
||||
}
|
||||
|
||||
func testConvenienceInitializerCanEnforceFixedDecimals() {
|
||||
let formatter = NumberFormatter(numberStyle: .percent, fixedDecimals: 2)
|
||||
XCTAssertEqual(formatter.locale.identifier, "en-US")
|
||||
XCTAssertEqual(formatter.numberStyle, .percent)
|
||||
XCTAssertEqual(formatter.minimumFractionDigits, 2)
|
||||
XCTAssertEqual(formatter.maximumFractionDigits, 2)
|
||||
}
|
||||
|
||||
func testConvenienceInstanceGeneratesValidDateStringForDollars() {
|
||||
let value = 123_456_789.123
|
||||
let formatter = NumberFormatter(numberStyle: .currency)
|
||||
let result = formatter.string(from: NSNumber(value: value))
|
||||
XCTAssertEqual(result, "$123,456,789.12")
|
||||
}
|
||||
|
||||
func testConvenienceInstanceGeneratesValidDateStringForSwedishKrona() {
|
||||
let value = 123_456_789.123
|
||||
let locale = Locale(identifier: "sv-SE")
|
||||
let formatter = NumberFormatter(numberStyle: .currency, locale: locale)
|
||||
let result = formatter.string(from: NSNumber(value: value))
|
||||
XCTAssertEqual(result, "123 456 789,12 kr")
|
||||
}
|
||||
|
||||
func testPercentFormatterGeneratesValidStringWithTwoDecimals() {
|
||||
let value = 0.09156
|
||||
let formatter = NumberFormatter.percent(decimals: 2)
|
||||
let result = formatter.string(from: NSNumber(value: value))
|
||||
XCTAssertEqual(result, "9.16%")
|
||||
}
|
||||
|
||||
func testPercentFormatterGeneratesValidStringWithZeroDecimals() {
|
||||
let value = 0.09156
|
||||
let formatter = NumberFormatter.percent(decimals: 0)
|
||||
let result = formatter.string(from: NSNumber(value: value))
|
||||
XCTAssertEqual(result, "9%")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// NumberFormatter+UtilTests.swift
|
||||
// SwiftKit
|
||||
//
|
||||
// Created by Daniel Saidi on 2022-10-19.
|
||||
// Copyright © 2012 Daniel Saidi. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftKit
|
||||
import XCTest
|
||||
|
||||
class NumberFormatter_UtilTests: XCTestCase {
|
||||
|
||||
func testStringForDoubleReturnsValidResult() {
|
||||
let value = 0.09156
|
||||
let formatter = NumberFormatter.percent(decimals: 2)
|
||||
let result = formatter.string(for: value)
|
||||
XCTAssertEqual(result, "9.16%")
|
||||
}
|
||||
|
||||
func testStringForIntReturnsValidResult() {
|
||||
let value: Int = 9
|
||||
let formatter = NumberFormatter.percent(decimals: 2)
|
||||
let result = formatter.string(for: value)
|
||||
XCTAssertEqual(result, "900.00%")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue