原文:Swift DateFormatter Cheatsheet [+Formulas, Parsing]
了解如何使用
DateFormatter从日期中解析、格式化和提取日期组件。使用 Cheatsheet 创建DateFormatter的公式。
在 Swift 中操作和格式化日期是一项常见任务。本文介绍了使用 DateFormatter、Date 和其他结构体的示例,这些结构体支持从日期和日期字符串中解析、格式化和获取日期组件。
Date Formulas 速查表
| Formulas | 输出样式 |
|---|---|
| yy.MM.dd | 23.01.16 |
| yyyy/MM/dd | 2023/01/16 |
| yyyy-MM-dd HH:mm | 2023-01-16 00:10 |
| MMM d, h:mm a | Jan 16, 0:10 AM |
| yyyy, MMM d,EEEE | 2023, Jan 16, Monday |
| yyyy-MM-dd’T’HH:mm:ssZ | 2023-01-16T00:10:00-0600 |
Date Format 速查表
| FORMULA | 描述 | 示例 |
|---|---|---|
| yyyy | 4位数字的年份 | 2022 |
| yy | 2位数字的年份 | 22 |
| M | 1 或 2 位数月份 | 8 |
| MM | 2 位数月份 | 08 |
| MMM | 数字+月 | 8月 |
| MMMM | 本地化月份 | 八月 |
| d | 1 或 2 位数的月份日期 | 2 |
| DD | 2 位数的月份日期 | 02 |
| D | 一年中的第几天 | 215 |
| HH | 2 位数小时(24 小时格式) | 13 |
| h | 1 或 2 位数小时(12 小时格式) | 1 |
| hh | 2 位数小时(12 小时格式) | 01 |
| H | 1 或 2 位数小时(24 小时格式 | 13 |
| m | 1 或 2 位数字分钟 | 2 |
| mm | 2 位数字分钟 | 02 |
| s | 1 或 2 位数字秒 | 2 |
| ss | 2 位秒数 | 02 |
| a | 12 小时格式的 AM/PM | PM |
使用 DateFormatter 将日期格式化为字符串
DateFormatter 上的 dateFormat 属性指定 DateFormatter 实例如何解析和格式化日期。将 dateFormat 设置为格式化字符串后,使用格式化的日期字符串调用 date(from:) 将日期字符串解析为 Date:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let date = dateFormatter.date(from: "01/16/2023")
print(date) // Optional(2023-01-16 00:10:00 +0000)
日期格式(dateStyle)、时间格式(timeStyle)
DateFormatter 有一个用于指定日期的日期格式的接口,即 dateStyle 属性。
DateFormatter 还有另一个用于指定日期时间格式的接口,即 timeStyle 属性。
| 值 | 描述 | dateStyle | timeStyle |
|---|---|---|---|
| .none | 不显示时间/日期 | - | - |
| .short | 时间/日期以短格式显示 | 11/23/1937 | 3:30 PM |
| .medium | 时间/日期以中等格式显示 | Nov 23, 1937 | 3:30:32 PM |
| .long | 时间/日期以长格式显示 | November 23, 1937 | 3:30:32 PM PST |
| .full | 时间/日期以最详细的格式显示,包括星期和纪元/时区和秒 | Tuesday, April 12, | |
| 1952 AD | 3:30:32 PM Pacific | ||
| Standard Time |
// 自定义 dateStyle
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
let dateString = dateFormatter.string(from: Date())
print(dateString) // "Jan 16, 2023"
// 自定义 timeStyle
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .medium
let timeString = dateFormatter.string(from: Date())
print(timeString) // "00:10:00 AM"
本地化(locale)
要控制格式化日期中的语言和区域特定信息,请使用 DateFormatter 上的 locale 属性。
// 将 locale 属性设置为法国
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM d, yyyy"
dateFormatter.locale = Locale(identifier: "fr_FR")
let date = dateFormatter.string(from: Date())
print(date) // "janvier 16, 2023"
// 将 locale 属性设置为中国
let formatter = DateFormatter() // 1.实例化
formatter.locale = Locale(identifier: "zh_CN") // 2.设置本地化信息
formatter.dateStyle = .short // 3.设置日期风格
formatter.timeStyle = .none // 4.设置时间风格
formatter.dateFormat = "yyyy-MM-dd" // 5.设置自定义日期和时间格式
formatter.timeZone = TimeZone(abbreviation: "GMT+8:00") // 6.设置时区
要将locale 属性设置为用户的设备设置,请使用 .autoupdatingCurrent:
dateFormatter.locale = Locale.autoupdatingCurrent
日历(calendar)
要控制用于格式化日期的日历,请使用 DateFormatter 上的 calendar 属性。
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM d, yyyy"
dateFormatter.calendar = Calendar(identifier: .islamic)
let date = dateFormatter.string(from: Date())
print(date) // "Jumada II 22, 1444"
Calendar 速查表
| Calendar | 描述 |
|---|---|
| gregorian | 世界上大部分地区使用的公历 |
| buddhist | 泰国和其他佛教徒占多数的国家使用的佛历 |
| chinese | 中国农历,在中国和其他拥有大量华人人口的国家使用 |
| coptic | 科普特历,用于科普特东正教教堂 |
| ethiopicAmeteAlem | 埃塞俄比亚历,也称为埃塞俄比亚东正教特瓦赫多教会历 |
| ethiopicAmeteMihret | 埃塞俄比亚历,也称为埃塞俄比亚东正教特瓦赫多教会历 |
| hebrew | 以色列和其他犹太社区使用的希伯来历 |
| iso8601 | ISO 8601 日历,日期和时间表示的国际标准 |
| indian | 印度国历,用于印度和其他拥有大量印度人口的国家 |
| islamic | 世界各地穆斯林社区使用的伊斯兰历 |
| islamicCivil | 世界各地穆斯林社区使用的伊斯兰历 |
| japanese | 日本使用的日历 |
| persian | 波斯历,在伊朗和其他拥有大量波斯人口的国家使用 |
| roc | 中华民国历,用于台湾和其他华人社区 |
将字符串转换为日期
除了格式化日期和时间之外,还可以使用 DateFormatter 将字符串解析为日期。就像格式化日期一样,将 DateFormatter 上的 dateFormat 设置为日期字符串的格式。然后,调用 date(from:) 传入日期字符串以获取解析后的日期:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = "2023-01-16"
let date = dateFormatter.date(from: dateString)
print(date) // Optional(2023-01-16 00:10:00 +0000)
Date Components
DateComponents 是一个结构体,可以使用日期的特定组成部分,例如年、月或日。
通过 Date Components 创建 Date
要通过指定每个单独的日期组件在 Swift 中创建日期,请使用 DateComponents:
var components = DateComponents()
components.day = 15
components.month = 1
components.year = 2023
components.hour = 0
components.minute = 10
let date = Calendar.current.date(from: components)
通过 Date 获取 Date Components
要从 Date 中获取日期组件(例如天数),请使用 DateComponents:
// Use the user's set calendar
let calendar = Calendar.autoupdatingCurrent
// Get the year, month, and day from the date
let components = calendar.dateComponents(
[.year, .month, .day],
from: Date()
)
// Reference the date components
nowComponents.year
nowComponents.month
nowComponents.day
在 Swift 中解析和格式化日期
就是这样!通过使用 DateFormatter、Date、Calendar 和 DateComponents,你可以在 Swift 中解析、格式化和使用日期组件。
附件
DateExtensions.swift
extension Date {
/// 给定一个 UTC iSO8601 格式的字符串,创建一个 Date 对象
/// 参考:<https://medium.com/livefront/10-swift-extensions-we-use-at-livefront-8b84de32f77b>
///
/// let utcDateString = "2021-04-03T14:00:00.000Z"
/// let utcDate = Date.utcDate(from: utcDateString)
///
/// - Parameter utcString: 用于创建日期的字符串
/// - Returns: 根据给定字符串返回的日期
static func utcDate(from utcString: String) -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(abbreviation: "UTC")! // swiftlint:disable:this force_unwrapping
return formatter.date(from: utcString)
}
}
DateFormatterExtensions.swif
import Foundation
import CodableWrapper
extension DateFormatter {
/// 创建一个 iSO8601 格式 DateFormatter 实例的静态方法
/// 2022-04-27T02:12:12.185+0000
static let iso8601Full: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 3600 * 8) // 北京所在时区,东八区
formatter.calendar = Calendar(identifier: .iso8601)
return formatter
}()
}
final class ISO8601FullDateTransform: DateFormatterTransform {
init() {
super.init(dateFormatter: DateFormatter.iso8601Full)
}
}