Swift 3 關(guān)于Date的一些操作

前言

最近在寫關(guān)于日期的一些操作,所以整理了一下這方面的一些知識

本Demo使用的是playground.

我們以前使用的都是NSDate類進(jìn)行日期的操作,在Swift 3.0中,我們就可以使用更加Swift化的 Date (這是一個結(jié)構(gòu)體)

Date

Date的展示

我們知道Date是一個結(jié)構(gòu)體.Date雖然包含了日期中的所有信息,它本身是不能顯示在界面上的,這就得來依靠我們的String


Date 和 String 的 轉(zhuǎn)換

  1. 首先我們使用Date獲取當(dāng)前日期

     let currentdate = Date()
    
  2. 接下來初始化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)了真正的從DateDateComponents的轉(zhuǎn)換以及從日期的組成元素到日期對象的轉(zhuǎn)換.

關(guān)于DateComponentsCalendar,我是這么認(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

方法一:

接著使用CalendardateComponents:方法來計算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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末峰档,一起剝皮案震驚了整個濱河市败匹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌讥巡,老刑警劉巖掀亩,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異欢顷,居然都是意外死亡槽棍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門抬驴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炼七,“玉大人,你說我怎么就攤上這事怎爵√厥” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵鳖链,是天一觀的道長姆蘸。 經(jīng)常有香客問我,道長芙委,這世上最難降的妖魔是什么逞敷? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮灌侣,結(jié)果婚禮上推捐,老公的妹妹穿的比我還像新娘。我一直安慰自己侧啼,他們只是感情好牛柒,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著痊乾,像睡著了一般皮壁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哪审,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天蛾魄,我揣著相機與錄音,去河邊找鬼。 笑死滴须,一個胖子當(dāng)著我的面吹牛舌狗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扔水,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼痛侍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了铭污?” 一聲冷哼從身側(cè)響起恋日,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘹狞,沒想到半個月后岂膳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡磅网,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年谈截,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涧偷。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡簸喂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出燎潮,到底是詐尸還是另有隱情喻鳄,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布确封,位于F島的核電站除呵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏爪喘。R本人自食惡果不足惜颜曾,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秉剑。 院中可真熱鬧泛豪,春花似錦、人聲如沸侦鹏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽略水。三九已至价卤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聚请,已是汗流浹背荠雕。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驶赏,地道東北人炸卑。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像煤傍,于是被迫代替她去往敵國和親盖文。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

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