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