一、简介
DateFormatter常用于Date与String的互相转换。通过配置dateFormat
属性使其能够转换成不同需求的字符串,配置locale
属性使其能够适配不同的语言。
二、API
- 格式化上下文
open var formattingContext: Formatter.Context
public enum Context : Int {
case unknown = 0
case dynamic = 1
case standalone = 2
case listItem = 3
case beginningOfSentence = 4
case middleOfSentence = 5
}
该属性用在英文等语言中,输出的字符串首字母是否需要大写。(其它人的文章中说明的,并未测试。)
- 通过dateFormat进行日期与字符串的转换
open func string(from date: Date) -> String
open func date(from string: String) -> Date?
默认是使用Asia/Shanghai
时区,zh_CN
本地化,gregorian
日历。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let string = df.string(from: Date())
print(string)
//2020-12-16 14:37:55
let d = df.date(from: string)
print(d)
//Optional(2020-12-16 06:37:55 +0000)
- 通过dateStyle将日期转换成字符串
open class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style,
timeStyle tstyle: DateFormatter.Style) -> String
public enum Style : UInt {
case none = 0 //无输出
case short = 1 //2020/12/16 下午2:42
case medium = 2 //2020年12月16日 下午2:42:21
case long = 3 //2020年12月16日 GMT+8 下午2:42:21
case full = 4 //2020年12月16日 星期三 中国标准时间 下午2:42:21
}
print(DateFormatter.localizedString(from: Date(), dateStyle: .short, timeStyle: .long))
//2020/12/16 GMT+8 下午2:49:49
- 模板字符串
- 将字符串转换成规范的dateFormat字符串
open class func dateFormat(fromTemplate tmplate: String, options opts: Int,
locale: Locale?) -> String?
let a = DateFormatter.dateFormat(fromTemplate: "yyayy-MaM-dad", options: 0,
locale: Locale.current)
//Optional("yy/M/d a")
- 应用模板字符串
open func setLocalizedDateFormatFromTemplate(_ dateFormatTemplate: String)
其作用是先将dateFormatTemplate转换成规范的dateFormat字符串,再赋值给dateFormat
。
let df = DateFormatter()
df.setLocalizedDateFormatFromTemplate("yyayy-MaM-dad")
等价于
df.dateFormat = DateFormatter.dateFormat(fromTemplate: "yyayy-MaM-dad",
options: 0, locale: Locale.current)
print(df.dateFormat)
//Optional("yy/M/d a")
- 属性
- 行为
open class var defaultFormatterBehavior: DateFormatter.Behavior
public enum Behavior : UInt {
case `default` = 0
case behavior10_4 = 1040
}
open var formatterBehavior: DateFormatter.Behavior
默认为behavior10_4。
- 日期格式化字符串
open var dateFormat: String!
默认为""。
以dateFormat
为yyyy-MM-dd HH:mm:ss,结果为2020-12-16 15:19:55的情况下,在zh_CN
本地化来看。
G Era标志符 公元
y 年份 2020
Y
M 该年的第几月 12
w 该年的第几周 51
W 该月的第几周 3
D 该年的第几天 351
d 该月的第几天 16
F 该月的第几星期 3
E 周几 周三
e 该周的第几天 4
a Am/pm 下午
Q 第几季度 4
q
H 一天的第几小时(0-23) 15
k 一天的第几小时(1-24) 15
h am/pm的第几小时(1-12) 3
K am/pm的第几小时(0-11) 3
m 该小时的第几分钟 19
s 该分钟的第几秒 55
S 该秒的第几毫秒 978
z 时区 GMT+8
Z 时区 +0800
以上的字母支持用多个叠加,比如M:
M
不带前导零 (一月表示为1)。
MM
带前导零 (一月表示为01)。
MMM
缩写形式 (一月为1月)。
MMMM
完整月份名 (一月为一月)。
不同语言下显示不同,如MMM
在英语中为Jan
,MMMM
为January
。
若要直接显示上面的字母,则需要加上单引号''。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(df.string(from: Date()))
//2020-12-16 16:43:30
df.dateFormat = "yyyy-MM-dd HH:mm:'ss'"
print(df.string(from: Date()))
//2020-12-16 16:43:ss
- 风格
open var dateStyle: DateFormatter.Style
open var timeStyle: DateFormatter.Style
功能与dateFormat(fromTemplate tmplate: String, options opts: Int, locale: Locale?) -> String?
方法相同。
let df = DateFormatter()
df.timeStyle = .medium
df.dateStyle = .medium
print(df.string(from: Date()))
//2020年12月16日 下午3:58:27
dateStyle
、timeStyle
与dateFormat
都赋了值后,先赋值的无效。
let df = DateFormatter()
df.timeStyle = .medium
df.dateStyle = .medium
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(df.string(from: Date()))
//2020-12-16 16:03:06
- 本地化、时区、日历
open var locale: Locale!
open var timeZone: TimeZone!
open var calendar: Calendar!
默认都为current
,即本地化为zh_CN
,时区为Asia/Shanghai
,日历为gregorian
。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(df.string(from: Date()))
//2020-12-16 16:13:57
df.locale = Locale(identifier: "en_US")//英语
df.timeZone = TimeZone(secondsFromGMT: 3600)//0100时区
df.calendar = Calendar(identifier: .chinese)//农历
print(df.string(from: Date()))
//0037-11-02 09:13:57
- 日期
//开始日期
open var twoDigitStartDate: Date?
//默认日期
open var defaultDate: Date?
//公历开始时间
open var gregorianStartDate: Date?
twoDigitStartDate
默认为1950-01-01 00:00:00 +0000。
defaultDate
默认为nil。
gregorianStartDate
默认为1582-10-15 00:00:00 +0000。
- 其它
open var generatesCalendarDates: Bool
open var isLenient: Bool
open var doesRelativeDateFormatting: Bool
generatesCalendarDates
默认为false。当为true时,在解析日期时会返回NSCalendarDate
实例而不是NSDate
,但NSCalendarDate
在Swift中已不可用,因而generatesCalendarDates
已失效。
isLenient
默认为false,表示要严格按照dateFormat
来格式化。当为true时,即使字符串与dateFormat
有差距,也能成功转换为Date。
doesRelativeDateFormatting
默认为false。当为true时,会以前天、昨天、今天、明天、后天来显示日期而不是通过年月日来显示。
let df = DateFormatter()
df.dateStyle = .medium
df.timeStyle = .medium
print(df.string(from: Date() + 3600*24))
//2020年12月18日 下午4:12:41
df.doesRelativeDateFormatting = true
print(df.string(from: Date() + 3600*24))
//明天 下午4:12:41
- 标志符的替换
注意:标志符在不同的本地化下为不同的结果。
- 纪元标志符
open var eraSymbols: [String]!
open var longEraSymbols: [String]!
eraSymbols
默认为 ["公元前", "公元"]。
longEraSymbols
默认为 ["公元前", "公元"]。
在en_US
本地化下,
eraSymbols
默认为 ["BC", "AD"]。
longEraSymbols
默认为 ["Before Christ", "Anno Domini"]。
在dateFormat
中输入G、GG、GGG时,则会匹配eraSymbols
的内容。
输入GGGG时,则会匹配longEraSymbols
的内容。
let df = DateFormatter()
df.locale = Locale(identifier: "en_US")
df.dateFormat = "yyyy-MM-dd HH:mm:ss G GG GGG GGGG GGGGG GGGGGG"
print(df.string(from: Date()))
//2020-12-17 14:29:30 AD AD AD Anno Domini A AD
df.eraSymbols = ["a", "a"]
df.longEraSymbols = ["b", "b"]
print(df.string(from: Date()))
//2020-12-17 14:29:30 a a a b A a
- 月份标志符
open var monthSymbols: [String]!
open var shortMonthSymbols: [String]!
open var veryShortMonthSymbols: [String]!
open var standaloneMonthSymbols: [String]!
open var shortStandaloneMonthSymbols: [String]!
open var veryShortStandaloneMonthSymbols: [String]!
monthSymbols
和standaloneMonthSymbols
默认为 ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]。
shortMonthSymbols
和shortStandaloneMonthSymbols
默认为 ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]。
veryShortMonthSymbols
和veryShortStandaloneMonthSymbols
默认为 ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]。
在en_US
本地化下,
monthSymbols
和standaloneMonthSymbols
默认为 ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]。
shortMonthSymbols
和shortStandaloneMonthSymbols
默认为 ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]。
veryShortMonthSymbols
和veryShortStandaloneMonthSymbols
默认为 ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]。
standaloneMonthSymbols
、shortStandaloneMonthSymbols
、veryShortStandaloneMonthSymbols
这三种并未测试出效果,不知在何处使用。
在dateFormat
中输入M时,会匹配无前导零的数字。
输入MM时,会匹配有前导零的数字。
输入MMM时,会匹配shortMonthSymbols
的内容。
输入MMMM时,则会匹配monthSymbols
的内容。
输入MMMMM时,则会匹配veryShortMonthSymbols
的内容。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss M MM MMM MMMM MMMMM MMMMMM MMMMMMM"
print(df.string(from: Date()))
//2020-12-17 14:41:59 12 12 12月 十二月 12 000012 0000012
df.monthSymbols = ["a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]
df.shortMonthSymbols = ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"]
df.veryShortMonthSymbols = ["c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c"]
print(df.string(from: Date()))
//2020-12-17 14:41:59 12 12 b a c 000012 0000012
- 星期标志符
open var weekdaySymbols: [String]!
open var shortWeekdaySymbols: [String]!
open var veryShortWeekdaySymbols: [String]!
open var standaloneWeekdaySymbols: [String]!
open var shortStandaloneWeekdaySymbols: [String]!
open var veryShortStandaloneWeekdaySymbols: [String]!
weekdaySymbols
和standaloneWeekdaySymbols
默认为 ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]。
shortWeekdaySymbols
和shortStandaloneWeekdaySymbols
默认为 ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]。
veryShortWeekdaySymbols
和veryShortStandaloneWeekdaySymbols
默认为 ["日", "一", "二", "三", "四", "五", "六"]。
在en_US
本地化下,
weekdaySymbols
和standaloneWeekdaySymbols
默认为 ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]。
shortWeekdaySymbols
和shortStandaloneWeekdaySymbols
默认为 ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]。
veryShortWeekdaySymbols
和veryShortStandaloneWeekdaySymbols
默认为 ["S", "M", "T", "W", "T", "F", "S"]。
standaloneWeekdaySymbols
、shortStandaloneWeekdaySymbols
、veryShortStandaloneWeekdaySymbols
这三种并未测试出效果,不知在何处使用。
在dateFormat
中输入E、EE、EEE、eee时,会匹配shortWeekdaySymbols
的内容。
输入EEEE、eeee时,则会匹配weekdaySymbols
的内容。
输入EEEEE、eeeee时,则会匹配veryShortWeekdaySymbols
的内容。
输入e时,会匹配无前导零的数字(该周的第几天)。
输入ee时,会匹配前导零的数字(该周的第几天)。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss E EE EEE EEEE EEEEE e ee eee eeee eeeee"
print(df.string(from: Date()))
2020-12-17 16:41:14 周四 周四 周四 星期四 四 5 05 周四 星期四 四
df.weekdaySymbols = ["a", "a", "a", "a", "a", "a", "a"]
df.shortWeekdaySymbols = ["b", "b", "b", "b", "b", "b", "b"]
df.veryShortWeekdaySymbols = ["c", "c", "c", "c", "c", "c", "c"]
print(df.string(from: Date()))
2020-12-17 16:41:14 b b b a c 5 05 b a c
- 时间段标志符
open var amSymbol: String!
open var pmSymbol: String!
amSymbol
默认为 上午。
pmSymbol
默认为 下午。
在en_US
本地化下,
amSymbol
默认为 AM。
pmSymbol
默认为 PM。
在dateFormat
中输入a时会匹配amSymbol或pmSymbol的内容,输入多个a无影响。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss a aa"
print(df.string(from: Date()))
//2020-12-17 15:15:39 下午 下午
df.amSymbol = "午前"
df.pmSymbol = "午后"
//2020-12-17 15:15:39 午后 午后
print(df.string(from: Date()))
- 季度标志符
open var quarterSymbols: [String]!
open var shortQuarterSymbols: [String]!
open var standaloneQuarterSymbols: [String]!
open var shortStandaloneQuarterSymbols: [String]!
quarterSymbols
和standaloneQuarterSymbols
默认为 ["第一季度", "第二季度", "第三季度", "第四季度"]。
shortQuarterSymbols
和shortStandaloneQuarterSymbols
默认为 ["1季度", "2季度", "3季度", "4季度"]。
在en_US
本地化下,
quarterSymbols
和standaloneQuarterSymbols
默认为 ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]。
shortQuarterSymbols
和shortStandaloneQuarterSymbols
默认为 ["Q1", "Q2", "Q3", "Q4"]。
在dateFormat
中输入q、Q时,会匹配无前导零的数字。
输入qq、QQ时,会匹配有前导零的数字。
输入qqq时,会匹配shortStandaloneQuarterSymbols
的内容。
输入qqqq时,则会匹配standaloneQuarterSymbols
的内容。
输入QQQ时,则会匹配shortQuarterSymbols
的内容。
输入QQQQ时,则会匹配quarterSymbols
的内容。
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss q qq qqq qqqq Q QQ QQQ QQQQ"
print(df.string(from: Date()))
//2020-12-17 15:26:16 4 04 4季度 第四季度 4 04 4季度 第四季度
df.quarterSymbols = ["a", "a", "a", "a"]
df.shortQuarterSymbols = ["b", "b", "b", "b"]
df.standaloneQuarterSymbols = ["c", "c", "c", "c"]
df.shortStandaloneQuarterSymbols = ["d", "d", "d", "d"]
print(df.string(from: Date()))
//2020-12-17 15:26:16 4 04 d c 4 04 b a