swift Calendar

一、簡(jiǎn)介

Calendar封裝了有關(guān)時(shí)間系統(tǒng)的信息,其中定義了年的開始和長(zhǎng)度等。它提供有關(guān)日歷的信息怠硼,并支持日歷計(jì)算,例如獲取符合條件的Date或DateComponents等趾断。

二、API

  1. 初始化
  • 用戶當(dāng)前使用的日歷
public static var current: Calendar { get }

默認(rèn)為gregorian (current)

  • 自動(dòng)跟蹤用戶設(shè)置的日歷
public static var autoupdatingCurrent: Calendar { get }

默認(rèn)為gregorian (autoupdatingCurrent)

  • 通過identifier初始化
public init(identifier: Calendar.Identifier)

public enum Identifier {
        case gregorian//公歷
        case buddhist//佛歷
        case chinese//農(nóng)歷
        case coptic//科普特歷
        case ethiopicAmeteMihret//埃塞俄比亞歷
        case ethiopicAmeteAlem//埃塞俄比亞阿米特阿萊姆日歷
        case hebrew//希伯來(lái)歷
        case iso8601//國(guó)際標(biāo)準(zhǔn)歷法
        case indian//印度國(guó)定歷
        case islamic//伊斯蘭歷
        case islamicCivil//伊斯蘭希吉來(lái)日歷
        case japanese//和歷
        case persian//波斯歷
        case republicOfChina//民國(guó)紀(jì)年
        case islamicTabular//伊斯蘭天文歷
        case islamicUmmAlQura//伊斯蘭歷(烏姆庫(kù)拉)
}
let c = Calendar(identifier: .gregorian)//公歷
print(c)
//gregorian (fixed)
  1. 屬性
  • 日歷的標(biāo)識(shí)符
public var identifier: Calendar.Identifier { get }
let c = Calendar(identifier: .gregorian)//公歷
print(c.identifier)
//gregorian
  • 日歷的本地化
public var locale: Locale?

默認(rèn)為nil

  • 日歷的時(shí)區(qū)
public var timeZone: TimeZone

默認(rèn)為Asia/Shanghai (current)

  • 日歷的第一個(gè)工作日
public var firstWeekday: Int

默認(rèn)為1吩愧,表示為星期一芋酌。

  • 第一周的最少天數(shù)
public var minimumDaysInFirstWeek: Int

默認(rèn)為1,表示某月的第一周只有一天雁佳。

  1. 標(biāo)志符
  • 紀(jì)元標(biāo)志符
public var eraSymbols: [String] { get }
public var longEraSymbols: [String] { get }

locale屬性為en_US時(shí)脐帝,eraSymbols默認(rèn)為 ["BCE", "CE"]。
locale屬性為zh_CN時(shí)糖权,eraSymbols默認(rèn)為 ["公元前", "公元"]堵腹。

var c = Calendar(identifier: .gregorian)
c.locale = Locale(identifier: "en_US")
print(c.eraSymbols)
//["BCE", "CE"]
c.locale = Locale(identifier: "zh_CN")
print(c.eraSymbols)
//["公元前", "公元"]

locale屬性為en_US時(shí),longEraSymbols默認(rèn)為 ["Before Christ", "Anno Domini"]星澳。
locale屬性為zh_CN時(shí)疚顷,longEraSymbols默認(rèn)為 ["公元前", "公元"]。

  • 月份標(biāo)志符
public var monthSymbols: [String] { get }
public var shortMonthSymbols: [String] { get }
public var veryShortMonthSymbols: [String] { get }

//獨(dú)立月份標(biāo)志符
public var standaloneMonthSymbols: [String] { get }
public var shortStandaloneMonthSymbols: [String] { get }
public var veryShortStandaloneMonthSymbols: [String] { get }

locale屬性為en_US時(shí)禁偎,
monthSymbols默認(rèn)為 ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]腿堤。
shortMonthSymbols默認(rèn)為 ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]。
veryShortMonthSymbols默認(rèn)為 ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]如暖。

standaloneMonthSymbols默認(rèn)為 ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]笆檀。
shortStandaloneMonthSymbols默認(rèn)為 ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]。
veryShortStandaloneMonthSymbols默認(rèn)為 ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]盒至。

注:standaloneMonthSymbols之類的獨(dú)立屬性用于日歷標(biāo)題之類的地方酗洒。monthSymbols之類的非獨(dú)立屬性用于上下文("2020年12月18日 星期五"中的12月)士修。

  • 星期標(biāo)志符
public var weekdaySymbols: [String] { get }
public var shortWeekdaySymbols: [String] { get }
public var veryShortWeekdaySymbols: [String] { get }

public var standaloneWeekdaySymbols: [String] { get }
public var shortStandaloneWeekdaySymbols: [String] { get }
public var veryShortStandaloneWeekdaySymbols: [String] { get }

locale屬性為en_US時(shí),
weekdaySymbols默認(rèn)為 ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]樱衷。
shortWeekdaySymbols默認(rèn)為 ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]棋嘲。
veryShortWeekdaySymbols默認(rèn)為 ["S", "M", "T", "W", "T", "F", "S"]。

standaloneWeekdaySymbols默認(rèn)為 ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]箫老。
shortStandaloneWeekdaySymbols默認(rèn)為 ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]封字。
veryShortStandaloneWeekdaySymbols默認(rèn)為 ["S", "M", "T", "W", "T", "F", "S"]。

注:standaloneWeekdaySymbols之類的獨(dú)立屬性用于日歷標(biāo)題之類的地方耍鬓。weekdaySymbols之類的非獨(dú)立屬性用于上下文("2020年12月18日 星期五"中的星期五)阔籽。

  • 季度標(biāo)志符
public var quarterSymbols: [String] { get }
public var shortQuarterSymbols: [String] { get }

public var standaloneQuarterSymbols: [String] { get }
public var shortStandaloneQuarterSymbols: [String] { get }

locale屬性en_US時(shí),
quarterSymbols默認(rèn)為 ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]牲蜀。
shortQuarterSymbols默認(rèn)為 ["Q1", "Q2", "Q3", "Q4"]笆制。

standaloneQuarterSymbols默認(rèn)為 ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]。
shortStandaloneQuarterSymbols默認(rèn)為 ["Q1", "Q2", "Q3", "Q4"]涣达。

注:standaloneQuarterSymbols之類的獨(dú)立屬性用于日歷標(biāo)題之類的地方在辆。quarterSymbols之類的非獨(dú)立屬性用于上下文("2020年12月18日 星期五 第四季度"中的 第四季度)。

  • 時(shí)間段標(biāo)志符
public var amSymbol: String { get }
public var pmSymbol: String { get }

locale屬性為en_US時(shí)度苔,
amSymbol默認(rèn)為 AM匆篓。
pmSymbo默認(rèn)為 PM。

  1. 范圍
  • 指定組件的最小范圍限制
public func minimumRange(of component: Calendar.Component) -> Range<Int>?
public enum Component {
        case era//紀(jì)元
        case year//年
        case month//月
        case day//日
        case hour//時(shí)
        case minute//分
        case second//秒
        case weekday//周幾
        case weekdayOrdinal//本月的第幾個(gè)周幾
        case quarter//季度
        case weekOfMonth//一個(gè)月的周數(shù)
        case weekOfYear//一年的周數(shù)
        case yearForWeekOfYear//ISO8601標(biāo)準(zhǔn)下的年份
        case nanosecond//納秒
        case calendar//日歷
        case timeZone//時(shí)區(qū)
}

關(guān)于Component寇窑,可查看DateComponents的初始化方法了解詳細(xì)鸦概。

2月最少為28天,范圍為 1..<29甩骏。

let c = Calendar(identifier: .gregorian)
print(c.minimumRange(of: .day))
//Optional(Range(1..<29))
  • 指定組件的最大范圍限制
public func maximumRange(of component: Calendar.Component) -> Range<Int>?

大月有31天窗市,范圍為 1..<32。

let c = Calendar(identifier: .gregorian)
print(c.maximumRange(of: .day))
//Optional(Range(1..<32))
  • 小組件可以在大組件中使用的范圍
public func range(of smaller: Calendar.Component, in larger: Calendar.Component,
                  for date: Date) -> Range<Int>?

一年最多有366天饮笛,范圍為 1..<367咨察。

let c = Calendar(identifier: .gregorian)
print(c.range(of: .day, in: .year, for: Date()))
//Optional(Range(1..<367))
  • 指定日期所處的開始日期與持續(xù)時(shí)間
public func dateInterval(of component: Calendar.Component, start: inout Date, 
                         interval: inout TimeInterval, for date: Date) -> Bool

如果能成功計(jì)算開始日期與持續(xù)時(shí)間,則返回true福青。

如下如示摄狱,2020-12-18 07:45:49這個(gè)日期在.hour下的開始日期為2020-12-18 07:00:00,持續(xù)時(shí)間為3600.0无午,指的就是2020-12-18 07:00:00-2020-12-18 08:00:00這個(gè)范圍二蓝。

let c = Calendar(identifier: .gregorian)
var d = Date()
var t = 0.0
print(d, t)
//2020-12-18 07:45:49 +0000 0.0
print(c.dateInterval(of: .hour, start: &d, interval: &t, for: d))
//ture
print(d, t)
//2020-12-18 07:00:00 +0000 3600.0
  • 指定日期所處的日期范圍
public func dateInterval(of component: Calendar.Component, for date: Date)
                                                          -> DateInterval?

功能與上面方法相同,返回的是日期范圍指厌。

如下刊愚,2020-12-18 07:54:13在.hour下的日期范圍為
2020-12-18 07:00:00 +0000 to 2020-12-18 08:00:00 +0000

let c = Calendar(identifier: .gregorian)
let d = Date()
print(d)
//2020-12-18 07:54:13 +0000
print(c.dateInterval(of: .hour, for: Date()))
//Optional(2020-12-18 07:00:00 +0000 to 2020-12-18 08:00:00 +0000)
  • 指定日期的小組件位于大組件的排序位置
public func ordinality(of smaller: Calendar.Component, in larger: Calendar.Component,
                      for date: Date) -> Int?

如下,2020-12-18 08:33:00 +0000在上海時(shí)區(qū)的時(shí)間為16:33:00踩验,返回的17指的是在.hour下16時(shí)為當(dāng)天的第17個(gè)小時(shí)鸥诽,0時(shí)為第1個(gè)小時(shí)商玫。

let c = Calendar(identifier: .gregorian)
let d = Date()
print(d)
//2020-12-18 08:33:00 +0000
print(c.ordinality(of: .hour, in: .day, for: d))
//Optional(17)
  1. 日期的修改
  • 通過日期組件
public func date(byAdding components: DateComponents, to date: Date,
                 wrappingComponents: Bool = false) -> Date?

給日期增加時(shí)間組件的各組件值,獲得一個(gè)新日期牡借。

wrappingComponents為true時(shí)拳昌,當(dāng)組件值超時(shí)最大限制時(shí),會(huì)減去其最大值钠龙。
如下炬藤,當(dāng)給當(dāng)前日期增加了25小時(shí)后,實(shí)際上只增加了1小時(shí)碴里。

let c = Calendar(identifier: .gregorian)
let d = Date()
print(d)
//2020-12-18 08:51:51 +0000
print(c.date(byAdding: DateComponents(hour: 25), to: d, wrappingComponents: true))
Optional(2020-12-18 09:51:51 +0000)
  • 通過日歷組件
public func date(byAdding component: Calendar.Component, value: Int, to date: Date,
                 wrappingComponents: Bool = false) -> Date?

與上面方法不同的是沈矿,該方法只能一次更改單個(gè)組件的值,而上面方法可以同時(shí)更改多個(gè)組件的值咬腋。
wrappingComponents的作用也與上面方法一致羹膳。

let c = Calendar(identifier: .gregorian)
let d = Date()
print(d)
//2020-12-19 06:08:25 +0000
print(c.date(byAdding: .hour, value: 30, to: d, wrappingComponents: true))
//Optional(2020-12-19 12:08:25 +0000)
  1. 日期組件
  • 日期組件轉(zhuǎn)換為日期
public func date(from components: DateComponents) -> Date?
let c = Calendar(identifier: .gregorian)
print(c.date(from: DateComponents(year: 2020, month: 12, day: 12,
                                  hour: 12, minute: 12, second: 12)))
//Optional(2020-12-12 04:12:12 +0000)
  • 通過日歷組件將日期轉(zhuǎn)換為日期組件
public func dateComponents(_ components: Set<Calendar.Component>,
                           from date: Date) -> DateComponents

該方法會(huì)獲取屬性不完整的日期組件。

let c = Calendar(identifier: .gregorian)
print(c.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date()))
//year: 2020 month: 12 day: 19 hour: 14 minute: 20 second: 52 isLeapMonth: false 
  • 通過時(shí)區(qū)將日期轉(zhuǎn)換為日期組件
public func dateComponents(in timeZone: TimeZone, from date: Date) -> DateComponents

該方法會(huì)獲取屬性完整的日期組件根竿。

let c = Calendar(identifier: .gregorian)
print(c.dateComponents(in: TimeZone.current, from: Date()))
//calendar: gregorian (fixed) timeZone: Asia/Shanghai (current) era: 1 year: 2020 
//month: 12 day: 19 hour: 14 minute: 24 second: 56 nanosecond: 984720945 
//weekday: 7 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 3 weekOfYear: 51 
//yearForWeekOfYear: 2020 isLeapMonth: false 
  • 獲取兩個(gè)日期的差
public func dateComponents(_ components: Set<Calendar.Component>, from start: Date,
                           to end: Date) -> DateComponents

差值通過日期組件展示陵像。

let c = Calendar(identifier: .gregorian)
print(c.dateComponents([.hour, .minute, .second], from: Date(), to: Date()+10000))
//hour: 2 minute: 46 second: 40 isLeapMonth: false 
  • 獲取兩個(gè)日期組件的差
public func dateComponents(_ components: Set<Calendar.Component>, 
     from start: DateComponents, to end: DateComponents) -> DateComponents

差值通過日期組件展示。

let c = Calendar(identifier: .gregorian)
print(c.dateComponents([.hour, .minute, .second], from: DateComponents(hour: 10), 
                       to: DateComponents(hour: 12, minute: 12, second: 12)))
//hour: 2 minute: 12 second: 12 isLeapMonth: false 
  • 獲取指定日期對(duì)應(yīng)日歷組件的值
public func component(_ component: Calendar.Component, from date: Date) -> Int
let c = Calendar(identifier: .gregorian)
print(Date())
//2020-12-19 06:43:03 +0000
print(c.component(.hour, from: Date()))
//14
  1. 日期的運(yùn)算
  • 獲取指定日期的開始日期
public func startOfDay(for date: Date) -> Date
let c = Calendar(identifier: .gregorian)
print(Date())
//2020-12-19 06:44:32 +0000
print(c.startOfDay(for: Date()))
//2020-12-18 16:00:00 +0000
  • 比較兩日期對(duì)應(yīng)組件值的大小
public func compare(_ date1: Date, to date2: Date, 
                    toGranularity component: Calendar.Component) -> ComparisonResult

public enum ComparisonResult : Int {    
    case orderedAscending = -1//升序
    case orderedSame = 0//相等
    case orderedDescending = 1//降序
}

注:并不是單獨(dú)比較組件的值寇壳。比如.second時(shí)醒颖,2分1秒也會(huì)大于1分59秒。實(shí)際上是將日期轉(zhuǎn)換為秒壳炎,再比較大小泞歉。

let c = Calendar(identifier: .gregorian)
print(c.compare(Date(), to: Date()+59, toGranularity: .second).rawValue)
//-1
  • 兩日期對(duì)應(yīng)組件值是否相同
public func isDate(_ date1: Date, equalTo date2: Date, 
                   toGranularity component: Calendar.Component) -> Bool

注:并不是單獨(dú)比較組件的值。比如.second時(shí)冕广,2分1秒也會(huì)大于1分1秒疏日。實(shí)際上是將日期轉(zhuǎn)換為秒偿洁,再比較大小撒汉。

let c = Calendar(identifier: .gregorian)
print(c.isDate(Date(), equalTo: Date()+60, toGranularity: .second))
//false
  • 兩日期是否在同一天
public func isDate(_ date1: Date, inSameDayAs date2: Date) -> Bool
  • 指定日期是否屬于今天
public func isDateInToday(_ date: Date) -> Bool
  • 指定日期是否屬于昨天
public func isDateInYesterday(_ date: Date) -> Bool
  • 指定日期是否屬于明天
public func isDateInTomorrow(_ date: Date) -> Bool
  • 指定日期是否屬于周末
public func isDateInWeekend(_ date: Date) -> Bool

注意:有些地區(qū)的周末并不是周六與周日。

  • 獲取指定日期的周末開始日期與持續(xù)時(shí)間
public func dateIntervalOfWeekend(containing date: Date, start: inout Date,
                                  interval: inout TimeInterval) -> Bool

若能獲取到周末涕滋,該方法返回true睬辐。

如下,因?yàn)榻裉焓侵芰龇危虼酥苣┦菑慕裉扉_始溯饵,持續(xù)172800.0秒,也就是2天锨用。

let c = Calendar(identifier: .gregorian)
var d = Date()
var i = 0.0
print(d, i)
//2020-12-19 07:14:33 +0000 0.0
print(c.dateIntervalOfWeekend(containing: Date(), start: &d, interval: &i))
//true
print(d, i)
//2020-12-18 16:00:00 +0000 172800.0
  • 獲取指定日期的周末的范圍
public func dateIntervalOfWeekend(containing date: Date) -> DateInterval?

功能與上面方法相同丰刊,只不過直接返回日期間隔。

let c = Calendar(identifier: .gregorian)
print(c.dateIntervalOfWeekend(containing: Date()))
//Optional(2020-12-18 16:00:00 +0000 to 2020-12-20 16:00:00 +0000)
  • 返回指定日期的下一個(gè)周末開始日期與持續(xù)時(shí)間
public func nextWeekend(startingAfter date: Date, start: inout Date,
     interval: inout TimeInterval, direction: Calendar.SearchDirection = .forward) -> Bool

public enum SearchDirection {
        case forward//查詢?nèi)掌诟蟮姆较蛟鲇担轮苣?        case backward//查詢?nèi)掌诟蟮姆较蜃那桑现苣?}

若能獲取到周末寻歧,該方法返回true。

功能與dateIntervalOfWeekend方法大致相同秩仆。
不同在于码泛,如下,因?yàn)榻裉焓侵芰?code>nextWeekend會(huì)獲取到下一個(gè)星期的周末澄耍,而dateIntervalOfWeekend會(huì)獲取到本周末噪珊。

let c = Calendar(identifier: .gregorian)
var d = Date()
var i = 0.0
print(d, i)
//2020-12-19 07:35:25 +0000 0.0
print(c.dateIntervalOfWeekend(containing: Date(), start: &d, interval: &i))
//true
print(d, i)
//2020-12-18 16:00:00 +0000 172800.0
print(c.nextWeekend(startingAfter: Date(), start: &d, interval: &i))
//true
print(d, i)
//2020-12-25 16:00:00 +0000 172800.0
  • 獲取指定日期的下一個(gè)周末的范圍
public func nextWeekend(startingAfter date: Date, 
                        direction: Calendar.SearchDirection = .forward) -> DateInterval?

功能與上面方法相同,只不過直接返回日期間隔齐莲。

let c = Calendar(identifier: .gregorian)
print(Date())
//2020-12-19 07:42:47 +0000
print(c.nextWeekend(startingAfter: Date()))
//Optional(2020-12-25 16:00:00 +0000 to 2020-12-27 16:00:00 +0000)
  1. 日期的匹配
  • 匹配滿足日期組件(或最接近)的日期
public func enumerateDates(startingAfter start: Date, 
                           matching components: DateComponents, 
                           matchingPolicy: Calendar.MatchingPolicy, 
                           repeatedTimePolicy: Calendar.RepeatedTimePolicy = .first, 
                           direction: Calendar.SearchDirection = .forward, 
                           using block: (Date?, Bool, inout Bool) -> Void)

如果不可能完全匹配痢站,并且matchingPolicystrict,則會(huì)將nil傳遞給閉包铅搓,并且枚舉結(jié)束瑟押。
邏輯上,strict匹配將無(wú)限期地搜索到將來(lái)星掰,但如果找不到匹配項(xiàng)多望,則繼續(xù)進(jìn)行枚舉并沒有意義。
若已成功匹配日期氢烘,可通過在閉包中將inout Bool值設(shè)置為true來(lái)停止枚舉并函數(shù)返回怀偷。
匹配策略

public enum MatchingPolicy {
        //如果DateComponents的下一個(gè)更高組件沒有匹配的時(shí)間,算法將返回存在的現(xiàn)有時(shí)間播玖。
        //例如椎工,在夏令時(shí)過渡時(shí)間可能沒有2:37 am,那么結(jié)果將是3:00 am蜀踏。
        case nextTime

        //與nextTime相同维蒙,但會(huì)保留下一個(gè)組件值。
        //例如果覆,在夏令時(shí)過渡時(shí)間可能沒有2:37 am颅痊,那么結(jié)果將是3:37 am。
        case nextTimePreservingSmallerComponents

        //與nextTime相同局待,但會(huì)減小組件值和保留下一個(gè)組件值斑响。
        //例如,在夏令時(shí)過渡時(shí)間可能沒有2:37 am钳榨,那么結(jié)果將是1:37 am舰罚。
        case previousTimePreservingSmallerComponents

        //精確查詢匹配項(xiàng)
        //例如,在公歷中搜索2月29日薛耻,上面的三個(gè)枚舉選項(xiàng)可能改為選擇3月1日(如果年份不是閏年)营罢。
        case strict
}

結(jié)果選擇策略

public enum RepeatedTimePolicy {
        //有多個(gè)匹配結(jié)果時(shí),將返回第一個(gè)結(jié)果
        case first
        //有多個(gè)匹配結(jié)果時(shí)饼齿,將返回最后一個(gè)結(jié)果
        case last
}

查詢方向

public enum SearchDirection {
        case forward//向日期更大的方向查詢
        case backward//向日期更小的方向查詢
}

閉包

 (Date?, Bool, inout Bool) -> Void

Date?為匹配到的日期饲漾。
Bool為true時(shí)瘟滨,表示此日期為完全匹配日期組件。
inout Bool賦值為true后能颁,會(huì)停止遍歷杂瘸。

let c = Calendar(identifier: .gregorian)
c.enumerateDates(startingAfter: Date(), matching: DateComponents(month: 2, day: 29), 
        matchingPolicy: .nextTime, repeatedTimePolicy: .first) { (a, b, c) in
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            print(formatter.string(from: a!), b , c)
            if b {
                //b為true表示完全匹配日期組件
                //matchingPolicy為strict時(shí),所有結(jié)果的b都為true
                c = true//設(shè)置為true可停止遍歷
            }
        }

//2021-03-01 00:00:00 false false
//2022-03-01 00:00:00 false false
//2023-03-01 00:00:00 false false
//2024-02-29 00:00:00 true false
  • 獲取第一個(gè)滿足日期組件(或最接近)的日期
public func nextDate(after date: Date, matching components: DateComponents, 
                     matchingPolicy: Calendar.MatchingPolicy, 
                     repeatedTimePolicy: Calendar.RepeatedTimePolicy = .first, 
                     direction: Calendar.SearchDirection = .forward) -> Date?

功能與enumerateDates方法相同伙菊,但只返回第一個(gè)匹配的日期败玉。

let a = c.nextDate(after: Date(), matching: DateComponents(month: 2, day: 29), 
          matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(formatter.string(from: a!))
  • 日期是否匹配日期組件
public func date(_ date: Date, matchesComponents components: DateComponents) -> Bool
let c = Calendar(identifier: .gregorian)
print(Date())
//2020-12-21 07:53:08 +0000
print(c.date(Date(), matchesComponents: DateComponents(month: 12, day: 21)))
//true
  1. 日期的更改
  • 通過組件值更改日期
public func date(bySetting component: Calendar.Component, value: Int,
                                                          of date: Date) -> Date?

枚舉參數(shù)可查看enumerateDates方法。
更改組件值時(shí)通常會(huì)要求同時(shí)更高或耦合的組件镜硕。例如运翼,將weekday設(shè)置為“星期四”的通常還要求更改day的組件值,并且可能還要求更改monthyear兴枯。
如果不存在滿足條件的日期血淌,此時(shí)會(huì)返回下一個(gè)可用日期。

當(dāng)更改組件值時(shí)财剖,更小組件值會(huì)重置悠夯。例如將month變成3,那么結(jié)果會(huì)變成03-01 00:00:00

let c = Calendar(identifier: .gregorian)
print(Date())
//2020-12-21 07:29:09 +0000
let d = c.date(bySetting: .month, value: 3, of: Date())
//Optional(2021-02-28 16:00:00 +0000)
print(d)
  • 通過時(shí)分秒更改日期
public func date(bySettingHour hour: Int, minute: Int, second: Int, of date: Date,
                 matchingPolicy: Calendar.MatchingPolicy = .nextTime, 
                 repeatedTimePolicy: Calendar.RepeatedTimePolicy = .first,
                 direction: Calendar.SearchDirection = .forward) -> Date?

枚舉參數(shù)可查看enumerateDates方法躺坟。
如果不存在滿足條件的日期沦补,此時(shí)會(huì)返回下一個(gè)可用日期。

let c = Calendar(identifier: .gregorian)
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(formatter.string(from: Date()))
//2020-12-21 15:48:26
let a = c.date(bySettingHour: 11, minute: 12, second: 13, of: Date())
print(formatter.string(from: a!))
//2020-12-21 11:12:13
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咪橙,一起剝皮案震驚了整個(gè)濱河市夕膀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌美侦,老刑警劉巖产舞,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菠剩,居然都是意外死亡易猫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門赠叼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)擦囊,“玉大人违霞,你說我怎么就攤上這事嘴办。” “怎么了买鸽?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵涧郊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我眼五,道長(zhǎng)妆艘,這世上最難降的妖魔是什么彤灶? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮批旺,結(jié)果婚禮上幌陕,老公的妹妹穿的比我還像新娘。我一直安慰自己汽煮,他們只是感情好搏熄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暇赤,像睡著了一般心例。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鞋囊,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天止后,我揣著相機(jī)與錄音,去河邊找鬼溜腐。 笑死译株,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挺益。 我是一名探鬼主播古戴,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼矩肩!你這毒婦竟也來(lái)了现恼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤黍檩,失蹤者是張志新(化名)和其女友劉穎叉袍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刽酱,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喳逛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棵里。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片润文。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖殿怜,靈堂內(nèi)的尸體忽然破棺而出典蝌,到底是詐尸還是另有隱情,我是刑警寧澤头谜,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布骏掀,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏截驮。R本人自食惡果不足惜笑陈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葵袭。 院中可真熱鬧涵妥,春花似錦、人聲如沸坡锡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)娜氏。三九已至拳缠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贸弥,已是汗流浹背窟坐。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绵疲,地道東北人哲鸳。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盔憨,于是被迫代替她去往敵國(guó)和親徙菠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容