前言
最近在寫關于日期的一些操作,所以整理了一下這方面的一些知識
本Demo使用的是playground.
我們以前使用的都是 NSDate
類進行日期的操作,在Swift 3.0中,我們就可以使用更加Swift化的 Date
(這是一個結構體)

Date
Date的展示
我們知道 Date
是一個結構體.Date雖然包含了日期中的所有信息,它本身是不能顯示在界面上的,這就得來依靠我們的 String
Date 和 String 的 轉換
-
首先我們使用
Date
獲取當前日期let currentdate = Date()
-
接下來初始化
DateFormatter
用來在Date 和 String 之間相互轉換
關于 DateFormatter
,從字面理解吧,這就是一個格式化的工具.你有了 Date
,你需要提供 Date
的展示方式,畢竟每個國家他的日期顯示的格式都不大相同吧,這取決你自己的需求
let dateformatter = DateFormatter()
所以你在將 Date
轉換為 String
之前 你需要告訴 DateFormatter
你需要顯示的字符串的結果的格式
//這里格式有5種 根據自己的需求去設置枚舉值
dateformatter.dateStyle = .full dateformatter.timeStyle = .long
3.你有了一個Date,也指定了一個DateFormatter的格式化的方法,接下來我們就可以來用String 來描述這個Date了
let dateString = dateformatter.string(from: currentdate)
自定義格式
當你覺得枚舉值中輸出的格式, 無法滿足你的要求,你要自定義日期的輸出格式的話.你需要格式化你的日期字符串,具體的請參考
http://unicode.org/reports/tr35/tr356.html#Date_Format_Patterns//EEEE:表示星期幾(Monday),使用1-3個字母表示周幾的縮寫
//MMMM:月份的全寫(October),使用1-3個字母表示月份的縮寫
//dd:表示日期,使用一個字母表示沒有前導0
//YYYY:四個數字的年份(2016)
//HH:兩個數字表示的小時(02或21)
//mm:兩個數字的分鐘 (02或54)
//ss:兩個數字的秒
//zzz:三個字母表示的時區
你現在已經有了一個格式化日期的 dateformatter
,既然枚舉格式無法滿足,你需要提供自己的格式給 dateformatter
(這是一個String 的字符串)
dateformatter.dateFormat = quot; YYYY - MM - dd HH:mm:ssquot;
然后還是使用DateFormatter的 func string(from: Date)
方法
let customDate = dateformatter.string(from: currentdate)
把既定格式的字符串轉化為Date
我們需要給定一個日期格式的字符串,接著指定格式化的方法,最后得到一個代表輸入字符串的Date
var string1 = quot;2016-10-05quot; dateformatter.dateFormat = quot; YYYY - MM - ddquot; var newDate = dateformatter.date(from: string1)
quot;拆分quot;Date
很多時候你有一個Date,你可能只是需要它的day,month,hour 等的值
DateComponents
通常和 Calendar
結合起來使用. Calendar
實現了真正的從 Date
到 DateComponents
的轉換以及從日期的組成元素到日期對象的轉換.
關于 DateComponents
和 Calendar
,我是這么認為的,你有了一個Date,要quot;拆分quot;Date,來找出自己需要的.可能是今天是幾月幾號,現在幾點了這種類似的.我們的 DateComponents
就是你的同伙,幫著你把Date活生生的拆了. Calendar
就是日歷,它提供了日歷的計算
首先我們獲取現在的 calendar
let calendar = Calendar.current
簡單的說就是用 calendar
的 拆分工具
把 Date
拆了
let dateComponents = calendar.dateComponents([.year,.month, .day, .hour,.minute,.second], from: currentdate )
這樣你就可以拿到你需要的
從 DateComponents 轉化為 Date
你可以把 Date
拆開,同樣的,你也可以使用零件(day,month)把Date拼回去
裝上去之前,我們先要拿到零件盒 DateComponents
var components = DateComponents()
接著定制我們的零件
components.year = 2016 components.day = 10 components.month = 11
你也可以設置時區 使用TimeZone 函數(使用時區的縮寫)
關于時區的縮寫網址: http://www.icoa.cn/a/611.html
components.timeZone = TimeZone(abbreviation: quot;GMTquot;)
有了完整的零件,接著我們就可以拼出來Date了
var newDate1 = calendar.date(from: components)
Date的比較
我們經常需要比較兩個Date ,在此之前 讓我們先創建兩個Date
String -gt; Date
我們可以設置自定義格式化的方法,通過用戶的輸入來將一個 String
轉化為一個 Date
注: 需要注意的是你輸入的格式,需要和格式化的時候的匹配
dateformatter.dateFormat = quot;MMM dd,yyyyquot; var dateAsString = quot;Oct 01,2017quot; var date1 = dateformatter.date(from: dateAsString) var dateNSVersion = date1 as! NSDate dateAsString = quot;Oct 02,2015quot; var date2 = dateformatter.date(from: dateAsString)
關于上面的為什么需要 NSDate
,下面會說到
比較的第一種方式
earlierDate和 laterDate 函數(這是NSDate 類中的方法,Date中并沒有 ,所以只有強制轉化為NSDate了)
原理如下: return date1 gt;= date2 ? date1 : date2
判斷date1 和 date2 的 quot;gt;=quot; 關系 是 返回date1, 否 返回date2
兩者原理一樣
舉個栗子
dateNSVersion.earlierDate(date2!) dateNSVersion.laterDate(date2!)
比較的第二種方法
使用的是compare方法以及 comparisonResult(枚舉類型,表示升序,降序,還是相等)
先舉個栗子 date1 lt; date2 升序排列
if date1?.compare(date2!) == .orderedAscending { print(quot;lt;quot;) }
相等的 date1 = date2 相等
if date1?.compare(date2!) == .orderedSame { print(quot; = quot;) }
降序排列的 date1 gt; date2 降序排列
if date1?.compare(date2!) == .orderedDescending { print(quot;lt;quot;) }
第三種方法 timeInterval,使用的是時間間隔來比較
它做的就是獲取每個日期以來的時間間隔
關于timeIntervalSinceReferenceDate
if (date1?.timeIntervalSinceReferenceDate)! - (date2?.timeIntervalSinceReferenceDate)! gt;= 0{ print(quot;大于等于quot;) } else{ print(quot;小于quot;) }
計算未來或者過去的日期
方法-: 一個一個改 使用默認的Calendar.Component
我們想讓給月份加2,天數加10
let monthsToAdd = 2 let daysToAdd = 10
接下來我們先給月份加
var calculatedDate = Calendar.current.date(byAdding: Calendar.Component.month, value: monthsToAdd, to: currentdate)
然后在這個基礎上再給day加
calculatedDate = Calendar.current.date(byAdding: .day, value: daysToAdd, to: currentdate)
如果你要加年月日,時分秒,很多的話 這樣會很麻煩 就有了第二種方法
方法二: 直接給定一個DateComponents對象,然后設置年月日等
我們還是拿到我們的零件盒 DateComponents
,接著拿上需要更換的零件(month,day)
var newDateComponent = DateComponents() newDateComponent.month = monthsToAdd newDateComponent.day = daysToAdd
最后把零件盒里面的零件裝到Date上(相比于第一種,把所有更改一次性完成)
calculatedDate = Calendar.current.date(byAdding: newDateComponent, to: currentdate)
方法三:時間間隔的方法TimeInterval
第三種計算另一個日期方式不推薦對時間跨度大的情況使用,因為由于閏秒,閏年,夏令時等等會導致這種方式產生出錯誤結果。該方式的想法是給當前日期加上一個特定的時間間隔。我們會使用 Date
類的 addingTimeInterval:
方法來實現這個目的。下面的例子中我們算出來一個相當于是 2 小時的時間間隔,然后把它加到當前日期上:
let hoursToAddInSeconds: TimeInterval = 120 * 60
calculatedDate = currentdate.addingTimeInterval(hoursToAddInSeconds)
計算過去的時間 和計算未來的時間一樣
let numberOfDays = -360 calculatedDate = Calendar.current.date(byAdding: .day, value: numberOfDays, to: currentdate)
計算時間的差值
我們還是使用上面定義的兩個Date
方法一:
接著使用 Calendar
的 dateComponents:
方法來計算Date的差值,如果你的第一個Date 比第二個Date小,那么結果就是負數
var diffDateComponents1 = Calendar.current.dateComponents([.year,.month,.day], from: date1!, to: date2!)
方法二 :
使用時間間隔的方法, DateComponentsFormatter
你需要定制你的格式.你是需要所有的年月日,還是只需要年,或者月之類
let dateComponentsFormatter = DateComponentsFormatter() dateComponentsFormatter.unitsStyle = .full
unitsStyle
unitsStyle 屬性告訴 dateComponentsFormatter 描述日期差值的那個字符串的格式應該是什么樣的,關于枚舉值:看文檔吧,這里不贅述
let interval = date2?.timeIntervalSince(date1!) dateComponentsFormatter.string(from: interval!)
方法三:
我們把 DateComponents
認為是零件盒,里面有month.day等的零件,而
dateComponentsFormatter
也就是我們這個零件盒的格式.定制我們的零件盒格式 allowedUnits
,具體到這里就是說我們的零件盒里面只有年月日,所以比較完返回的格式就是年月日這種的.因為我們只有年月日,所以不會出現別的零件,像時分秒這種的
dateComponentsFormatter.allowedUnits = [.year,.month,.day]
如果你想知道他們之家差了多少天. 就可以只在盒子里面放上天的零件,這樣你得到的就是這兩個Date相差多少天
dateComponentsFormatter.allowedUnits = [.day] let autoFormattedDifference = dateComponentsFormatter.string(from: date1!, to: date2!)
總結
到這里就已經結束了,寫了好久才完成.我并沒有直接的給出所有的這些代碼的運行結果,我希望大家可以去試試,只有動手去做才會記住.而且Swift為我們提供了一個很好的工具 playground.
這里有篇文章寫的很好: http://www.jianshu.com/p/3e5f6cb1c31c
就是根據這篇文章才寫出來這個小Demo,希望可以得到分享
最后附上本次使用的Demo :這是一個playground寫的.希望可以幫到大家,如果你覺得還可以的話,請給顆星( ^__^ ) 嘻嘻……
playground: https://github.com/xiangtaiduo/DateOperation
Tags: Swift
文章來源:http://www.jianshu.com/p/a6275cc54e04