在上一节,主要讲解了如下日期对象
- Date: 表示
单个时间点。 - DateFormatter: 用于日期和字符串
互相转换 - DateComponents: 指定年、月、日、小时、分钟等
时间单位,以表示时间点或持续时间 - Calendar: 用于 Date 和 DateComponents 之间转换
使用 description description(with:)以可读的形式打印Date到 Xcode 控制台,但它们仅用于调试目的, 不能用于向用户提供日期和时间信息。
本章会详细介绍 formatter() 和 DateFormmatter 日期格式化知识
formatted()
在 Swift 5.5 和 iOS 15 及更高版本App,可以使用formatted()格式化方法
// Locale随着用户修改自动更新
var userLocale = Locale.autoupdatingCurrent
// 公历
var gregorianCalendar = Calendar(identifier: .gregorian)
gregorianCalendar.locale = userLocale
var swiftDebutComponents = DateComponents(
year: 2014,
month: 6,
day: 2
)
var swiftDebutDate = gregorianCalendar.date(from: swiftDebutComponents)!
print("\(swiftDebutDate.formatted())")
根据区域设置输出内容不同,我的电脑输出: 2014/6/2 0:00
formatted() 不同长度显示:
formatted(date:time:)
print("Date的各种格式")
print("1. 完全形式: \(swiftDebutDate.formatted(date: .complete, time: .omitted))")
print("2. 简写: \(swiftDebutDate.formatted(date: .abbreviated, time: .omitted))")
print("3. Long: \(swiftDebutDate.formatted(date: .long, time: .omitted))")
print("4. Numeric: \(swiftDebutDate.formatted(date: .numeric, time: .omitted))")
print("时间的各种格式:")
print("1. Complete: \(swiftDebutDate.formatted(date: .omitted, time: .complete))")
print("2. Shortened: \(swiftDebutDate.formatted(date: .omitted, time: .shortened))")
print("3. Standard: \(swiftDebutDate.formatted(date: .omitted, time: .standard))")
print("日期和时间一起显示")
print("1. Complete/Complete: \(swiftDebutDate.formatted(date: .complete, time: .complete))")
print("2. Abbreviated/Shortened: \(swiftDebutDate.formatted(date: .abbreviated, time: .shortened))")
print("3. Numeric/Shortened: \(swiftDebutDate.formatted(date: .numeric, time: .shortened))")
Date的各种格式
1. 完全形式: 2014年6月2日 星期一
2. 简写: 2014年6月2日
3. Long: 2014年6月2日
4. Numeric: 2014/6/2
时间的各种格式:
1. Complete: GMT+8 0:00:00
2. Shortened: 0:00
3. Standard: 0:00:00
日期和时间一起显示
1. Complete/Complete: 2014年6月2日 星期一 GMT+8 0:00:00
2. Abbreviated/Shortened: 2014年6月2日 0:00
3. Numeric/Shortened: 2014/6/2 0:00
formatted() 日期和时间格式
使用 FormatStyle 对格式化的日期字符串进行更精细的控制。
let fancyDateString = swiftDebutDate.formatted(
Date.FormatStyle()
.year(.twoDigits) // 两位数字的年
.month(.wide) // 英文环境会输出`September`这样完整的单词
.day(.twoDigits) // 两位数字的天
)
print("年月日显示: \(fancyDateString)")
let style = Date.FormatStyle.dateTime // 使用 dateTime Format Style
.year(.defaultDigits)
.month(.abbreviated)
.day(.twoDigits)
.hour(.defaultDigits(amPM: .abbreviated))
.minute(.twoDigits)
.timeZone(.identifier(.long))
.era(.wide)
.dayOfYear(.defaultDigits)
.weekday(.abbreviated)
.week(.defaultDigits)
let superFancyDateString = swiftDebutDate.formatted(
style
)
print("完整dateTime日期: \(superFancyDateString)")
在我的电脑输出
年月日显示: 14年6月02日
完整dateTime日期: 公元2014年6月02日 周一 (周: 22) Asia/Shanghai 00:00
ISO8601Format()
在Swift 5.5和iOS 15及更高版本的App, 使用 ISO8601Format()将Date转换为ISO8601格式字符串
print("ISO 8601 格式: \(swiftDebutDate.ISO8601Format())")
ISO 8601 格式: 2014-06-01T16:00:00Z
使用Date.ISO8601FormatStyle对输出字符串进行更精细控制。
let customizedISO8601DebutDate = swiftDebutDate.ISO8601Format(
.iso8601
.weekOfYear() // 包含一年的第几周,以“W”开头
.year() // 包含年, 忽略月和日
// .month() // 注释月
// .day() // 注释天
.dateSeparator(.omitted) // `.omitted` 参数删掉日期的分隔符
.time(includingFractionalSeconds: true) // 包含时间并且包含秒显示
.timeSeparator(.colon) // 时/分使用:分隔符
)
print("自定义ISO 8601格式: \(customizedISO8601DebutDate).")
DateFormatter格式化
在 Swift 5.5 和 iOS 15 之前,使用DateFormatter转换字符串。
使用 small medium long full 等日期(dateStyle)和时间(timeStyle)格式
let swiftDebutDate = Date()
var myFormatter = DateFormatter()
myFormatter.dateStyle = .none
print("日期: none style: \(myFormatter.string(from: swiftDebutDate))")
myFormatter.dateStyle = .short
print("日期: short style: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.dateStyle = .medium
print("日期: medium style: \(myFormatter.string(from: swiftDebutDate))")
myFormatter.dateStyle = .long
print("日期: long style: \(myFormatter.string(from: swiftDebutDate))")
myFormatter.dateStyle = .full
print("日期: full style: \(myFormatter.string(from: swiftDebutDate))")
// 时间样式
myFormatter.timeStyle = .short
print("时间: short style: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.timeStyle = .medium
print("时间: short style: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.timeStyle = .long
print("时间: long style: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.timeStyle = .full
print("时间: full style: \(myFormatter.string(from: swiftDebutDate)).")
日期: none style:
日期: short style: 2023/6/28.
日期: medium style: 2023年6月28日
日期: long style: 2023年6月28日
日期: full style: 2023年6月28日 星期三
时间: short style: 2023年6月28日 星期三 上午8:06.
时间: short style: 2023年6月28日 星期三 上午8:06:35.
时间: long style: 2023年6月28日 星期三 GMT+8 上午8:06:35.
时间: full style: 2023年6月28日 星期三 中国标准时间 上午8:06:35.
用其他语言表示日期和时间
DateFormatter默认使用用户设置的首选语言, 我们一般是中文。可以指定其他语言的格式显示
let myFormatter = DateFormatter()
// 使用完整的日期和时间格式
myFormatter.dateStyle = .full
myFormatter.timeStyle = .full
myFormatter.locale = Locale(identifier: "en")
print("英语显示: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.locale = Locale(identifier: "en-US")
print("美国英语显示: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.locale = Locale(identifier: "fr")
print("法语显示: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.locale = Locale(identifier: "fr-CA")
print("加拿大法语: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.locale = Locale(identifier: "hr")
print("克罗地亚语: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.locale = Locale(identifier: "ko_KR")
print("韩语: \(myFormatter.string(from: swiftDebutDate)).")
英语显示: Monday, June 2, 2014 at 12:00:00 AM China Standard Time.
美国英语显示: Monday, June 2, 2014 at 12:00:00 AM China Standard Time.
法语显示: lundi 2 juin 2014 à 00:00:00 heure normale de la Chine.
加拿大法语: lundi 2 juin 2014 à 00:00:00 heure normale de Chine.
克罗地亚语: ponedjeljak, 2. lipnja 2014. u 00:00:00 (kinesko standardno vrijeme).
韩语: 2014년 6월 2일 월요일 오전 12시 0분 0초 중국 표준시.
自定义格式
除了内置格式外,可以使用DateFormatter自定义格式创建日期和时间字符串。
let myFormatter = DateFormatter()
// 更多格式可以参考
// http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns)
myFormatter.dateFormat = "y-MM-dd"
print("y-MM-dd 格式: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.dateFormat = "yy/MM/dd"
print("yy/MM/dd格式: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.dateFormat = "yyyy年M月dd日"
print("yyyy年M月dd日格式: \(myFormatter.string(from: swiftDebutDate)).")
myFormatter.dateFormat = "yyyy/MMMM/dd EEEE h:mm a zzzz"
print("yyyy/MMMM/dd EEEE h:mm a zzzz: \(myFormatter.string(from: swiftDebutDate)).")
y-MM-dd 格式: 2014-06-02.
yy/MM/dd格式: 14/06/02.
yyyy年M月dd日格式: 2014年6月02日.
yyyy/MMMM/dd EEEE h:mm a zzzz: 2014/六月/02 星期一 12:00 上午 中国标准时间.
将字符串转换为Date
设置期望的日期和时间字符串的格式,然后使用 DateFormatter 进行转换
更多日期格式可以查阅 Date_Format_Patterns。
// 定义日期格式
myFormatter.dateFormat = "yyyy/MM/dd hh:mm Z"
// 格式匹配,能正确转换
let newDate1 = myFormatter.date(from: "2019/06/03 12:08 -0700")
print("newDate1’s value is: \(newDate1?.description ?? "nil").")
// 格式不匹配,无法正确转换
let newDate2 = myFormatter.date(from: "一月 6, 2019, 12:08 PM PDT")
print("newDate2’s value is: \(newDate2?.description ?? "nil").")
newDate1’s value is: 2019-06-03 07:08:00 +0000.
newDate2’s value is: nil.