在 DateFormatter 中使用 NumberFormatter
Using a NumberFormatter within a DateFormatter
我正在尝试将我的 Date()
格式化为看起来像 Saturday, June 12th • 5PM - 12PM
。我已经能够通过以下 DateFormatter()
:
解决大部分问题
var date_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMMM d • HHa - HHa"
return formatter
}
这导致 Saturday, June 12 • 5PM - 12PM
我面临的挑战是了解如何添加序数后缀(即 12 -> 12th)。我在 NumberFormatter()
上看到了一点,但我不太确定如何将两者结合起来。
编辑:最终不得不为 5PM - 12PM
逻辑创建两种格式。
这看起来像:
var start_time_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMMM d • HHa -"
return formatter
}
var end_time_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "HHa"
return formatter
}
使用以下内容在视图中显示它:
Text("\(self.create_event_vm.start_time, formatter: self.start_time_formatter) \(self.create_event_vm.end_time, formatter: self.end_time_formatter)")
我知道这有点古怪,可以使用一些重构,但我希望获得预期的效果、测试,然后重构。
您可以在下面的函数中创建当天的第一个后缀
func getDaySuffix(from date: Date) -> String {
switch Calendar.current.component(.day, from: date) {
case 1, 21, 31: return "st"
case 2, 22: return "nd"
case 3, 23: return "rd"
default: return "th"
}
}
并结合您的代码:
let startDate = Date()
let endDate = Calendar.current.date(byAdding: .hour, value: 5, to: startDate)!
var startTimeFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "EEEE, MMMM d'\(getDaySuffix(from: startDate))' • ha - "
return formatter
}
var endTimeFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "ha"
return formatter
}
let startDateResult = startTimeFormatter.string(from: startDate) // "Thursday, June 18th • 2AM - "
let endDateResult = endTimeFormatter.string(from: endDate) // "7AM"
let finalResult = startDateResult + endDateResult // "Thursday, June 18th • 2AM - 7AM"
你走错了路。您需要创建一个 DateInterval 并使用其 DateIntervalFormatter 将其显示给用户。请注意,中午 12 点已经是另一天,因此您的日期间隔表示是错误的:
let dateA = DateComponents(calendar: .current, year: 2020, month: 6, day: 12, hour: 17, minute: 0).date!
let dateB = DateComponents(calendar: .current, year: 2020, month: 6, day: 13, hour: 0, minute: 0).date!
let di = DateInterval(start: dateA, end: dateB)
let dif = DateIntervalFormatter()
dif.dateTemplate = "EEEEMMMMdh"
dif.string(from: di) // "Friday, June 12, 5 PM – Saturday, June 13, 12 AM"
首先是一个有用的扩展Int+Ordinal.swift
:
extension Int {
/// `Int` ordinal suffix
enum Ordinal: String {
/// Suffix for numbers ending in `1` except 11
case st = "st"
/// Suffix for numbers snding in `2` except 12
case nd = "nd"
/// Suffix for numbers ending in `3` except 13
case rd = "rd"
/// Suffix otherwise
case th = "th"
}
/// Get `Ordinal` from `Int` `self`
var ordinal: Ordinal {
var mod = self % 100
if mod == 11 || mod == 12 || mod == 13 {
return .th
} else {
mod = mod % 10
if mod == 1 {
return .st
} else if mod == 2 {
return .nd
} else if mod == 3 {
return .rd
} else {
return .th
}
}
}
}
然后使用这个扩展和 DateFormatter
:
func string(from startDate: Date, to endDate: Date) -> String {
let formatter = DateFormatter()
// weekdayMonth
formatter.dateFormat = "EEEE, MMMM"
let weekdayMonth = formatter.string(from: startDate)
// day
formatter.dateFormat = "d"
var day = formatter.string(from: startDate)
if let dayValue = Int(day) {
day += dayValue.ordinal.rawValue
}
// timeFrom
formatter.dateFormat = "ha"
let timeFrom = formatter.string(from: startDate)
// timeTo
let timeTo = formatter.string(from: endDate)
return "\(weekdayMonth) \(day) • \(timeFrom) - \(timeTo)"
}
运行它:
let dateString = string(from: Date(), to: Date().addingTimeInterval(3600 * 4))
print(dateString) // "Wednesday, June 17th • 11PM - 3AM"
虽然我猜在这个例子中你不希望它 运行 到第二天! :)
我正在尝试将我的 Date()
格式化为看起来像 Saturday, June 12th • 5PM - 12PM
。我已经能够通过以下 DateFormatter()
:
var date_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMMM d • HHa - HHa"
return formatter
}
这导致 Saturday, June 12 • 5PM - 12PM
我面临的挑战是了解如何添加序数后缀(即 12 -> 12th)。我在 NumberFormatter()
上看到了一点,但我不太确定如何将两者结合起来。
编辑:最终不得不为 5PM - 12PM
逻辑创建两种格式。
这看起来像:
var start_time_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE, MMMM d • HHa -"
return formatter
}
var end_time_formatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "HHa"
return formatter
}
使用以下内容在视图中显示它:
Text("\(self.create_event_vm.start_time, formatter: self.start_time_formatter) \(self.create_event_vm.end_time, formatter: self.end_time_formatter)")
我知道这有点古怪,可以使用一些重构,但我希望获得预期的效果、测试,然后重构。
您可以在下面的函数中创建当天的第一个后缀
func getDaySuffix(from date: Date) -> String {
switch Calendar.current.component(.day, from: date) {
case 1, 21, 31: return "st"
case 2, 22: return "nd"
case 3, 23: return "rd"
default: return "th"
}
}
并结合您的代码:
let startDate = Date()
let endDate = Calendar.current.date(byAdding: .hour, value: 5, to: startDate)!
var startTimeFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "EEEE, MMMM d'\(getDaySuffix(from: startDate))' • ha - "
return formatter
}
var endTimeFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "ha"
return formatter
}
let startDateResult = startTimeFormatter.string(from: startDate) // "Thursday, June 18th • 2AM - "
let endDateResult = endTimeFormatter.string(from: endDate) // "7AM"
let finalResult = startDateResult + endDateResult // "Thursday, June 18th • 2AM - 7AM"
你走错了路。您需要创建一个 DateInterval 并使用其 DateIntervalFormatter 将其显示给用户。请注意,中午 12 点已经是另一天,因此您的日期间隔表示是错误的:
let dateA = DateComponents(calendar: .current, year: 2020, month: 6, day: 12, hour: 17, minute: 0).date!
let dateB = DateComponents(calendar: .current, year: 2020, month: 6, day: 13, hour: 0, minute: 0).date!
let di = DateInterval(start: dateA, end: dateB)
let dif = DateIntervalFormatter()
dif.dateTemplate = "EEEEMMMMdh"
dif.string(from: di) // "Friday, June 12, 5 PM – Saturday, June 13, 12 AM"
首先是一个有用的扩展Int+Ordinal.swift
:
extension Int {
/// `Int` ordinal suffix
enum Ordinal: String {
/// Suffix for numbers ending in `1` except 11
case st = "st"
/// Suffix for numbers snding in `2` except 12
case nd = "nd"
/// Suffix for numbers ending in `3` except 13
case rd = "rd"
/// Suffix otherwise
case th = "th"
}
/// Get `Ordinal` from `Int` `self`
var ordinal: Ordinal {
var mod = self % 100
if mod == 11 || mod == 12 || mod == 13 {
return .th
} else {
mod = mod % 10
if mod == 1 {
return .st
} else if mod == 2 {
return .nd
} else if mod == 3 {
return .rd
} else {
return .th
}
}
}
}
然后使用这个扩展和 DateFormatter
:
func string(from startDate: Date, to endDate: Date) -> String {
let formatter = DateFormatter()
// weekdayMonth
formatter.dateFormat = "EEEE, MMMM"
let weekdayMonth = formatter.string(from: startDate)
// day
formatter.dateFormat = "d"
var day = formatter.string(from: startDate)
if let dayValue = Int(day) {
day += dayValue.ordinal.rawValue
}
// timeFrom
formatter.dateFormat = "ha"
let timeFrom = formatter.string(from: startDate)
// timeTo
let timeTo = formatter.string(from: endDate)
return "\(weekdayMonth) \(day) • \(timeFrom) - \(timeTo)"
}
运行它:
let dateString = string(from: Date(), to: Date().addingTimeInterval(3600 * 4))
print(dateString) // "Wednesday, June 17th • 11PM - 3AM"
虽然我猜在这个例子中你不希望它 运行 到第二天! :)