DateInRegion 0.5.2

DateInRegion 0.5.2

测试已测试
Lang语言 SwiftSwift
许可 MIT
发布上次发布2015年11月
SPM支持 SPM

Jeroen Houtzager 维护。



  • 作者:
  • Hout

DateInRegion 是对 NSDate 的包装,暴露了 NSDateComponents, NSCalendar, NSTimeZone, NSLocale 和 NSDateFormatter 的属性。最好的方式是将它视为一个本地的(地区)时刻(日期)在时区(时间)框架下的日历系统中的时刻。意图是用 DateInRegion 替换您的 NSDate 用例,并获取相同的功能加上许多本地日期/日历/时区/格式化佳品。因此,它提供了在我创建这个库时寻求的灵活的日期函数。

提供一个对 NSDate 的扩展,您可以通过添加地区将 NSDate 对象映射到 DateInRegion 对象。

功能

  • 将对象用作 NSDate,即作为一个绝对时间。
  • 提供了许多 NSDate,NSCalendar,NSDateFormatter & NSDateComponent 变量和方法
  • 用任意组件组合初始化日期
  • DateInRegion 是不可变的,所以是线程安全的。它包含一个构造函数,可以轻松创建新的带有一些属性调整的 DateInRegion 实例。
  • 实现了带日期组件的日期加减运算符。例如:date + 2.days
  • 默认日期是 NSDate()
  • 默认日历是 NSCalendar.currentCalendar()
  • 默认时区是 NSTimeZone.defaultTimeZone()
  • 默认地区是 NSLocale.currentLocale()
  • 包含一个日期(NSDate)、一个日历(NSCalendar)、一个地区(NSLocale)和一个时区(NSTimeZone)属性
  • 实现了日期之间的 Equatable & Comparable 协议,使用了运算符。例如:==, !=, <, >, <=, >=
  • 实现了 Hashable 协议,因此日期可以用作字典中的键。

示例

查看 playground

import DateInRegion

// First create some regions
let local = DateRegion()
let india = DateRegion(calendarID: NSCalendarIdentifierIndian, timeZoneID: "IST", localeID: "en_IN")
let dubai = DateRegion(calendarID: NSCalendarIdentifierIslamic, timeZoneID: "GST", localeID: "ar_AE")
let newZealand = DateRegion(calendarID: NSCalendarIdentifierGregorian, localeID: "en_NZ", timeZoneID: "Pacific/Auckland")
let israel = DateRegion(calendarID: NSCalendarIdentifierHebrew, timeZoneID: "Asia/Jerusalem", localeID: "he_IL")
let china = DateRegion(calendarID: NSCalendarIdentifierChinese, timeZoneID: "CST", localeID: "zn_CH")
let magadan = DateRegion(calendarID: NSCalendarIdentifierGregorian, timeZoneID: "Asia/Magadan", localeID: "ru_RU")
let thailand = DateRegion(calendarID: NSCalendarIdentifierBuddhist, timeZoneID: "Asia/Bangkok", localeID: "th_TH")
let japan = DateRegion(calendarID: NSCalendarIdentifierBuddhist, timeZoneID: "Asia/Tokyo", localeID: "ja_JP")
let unalaska = DateRegion(calendarID: NSCalendarIdentifierGregorian, timeZoneID: "AKST", localeID: "en_US")
let utc = DateRegion(calendarID: NSCalendarIdentifierGregorian, timeZoneID: "UTC", localeID: "en_US_POSIX")


//: #### Initialisers
//: Create a new date object with the current date & time alike NSDate()
let now = DateInRegion()

//: Create a determined date
let newDate = DateInRegion(year: 2011, month: 2, day: 11)!

//: Create a determined date in a different time zone
let newYork = DateRegion(timeZoneID: "EST")
DateInRegion(fromDate: newDate, hour: 14, region: newYork)!

//: Mind that default values for DateInRegion(year etc) are taken from the reference date,
//: which is 1 January 2001, 00:00:00.000 in your default time zone and against your current calendar.

//: Week oriented initiailisations are also possible: first week of 2016:
let weekDate = DateInRegion(yearForWeekOfYear: 2016, weekOfYear: 1, weekday: 1)!
//: In Europe this week starts in 2015 despite the year for the week that is 2016.
//: That is because the Thursday of this week is in 2016 as specified by ISO 8601

// Conversions
let unalaskaDate = now.inRegion(unalaska)
let newYorkDate = now.inRegion(newYork)
let indiaDate = now.inRegion(india)
let dubaiDate = now.inRegion(dubai)
let israelDate = now.inRegion(israel)
let chinaDate = now.inRegion(china)
let newZealandDate = now.inRegion(newZealand)
let magadanDate = now.inRegion(magadan)
let japanDate = now.inRegion(japan)
let thailandDate = now.inRegion(thailand)
let utcDate = now.inRegion(utc)

// Or convert to local
let japanDate2 = DateInRegion(year: 2010, month: 4, day: 5, hour: 16, region: japan)!
let localDate = japanDate2.inLocalRegion()

// Now look in regional format
unalaskaDate.toString()
newYorkDate.toString()
indiaDate.toString()
dubaiDate.toString()
israelDate.toString()
chinaDate.toString()
magadanDate.toString()
japanDate.toString()
thailandDate.toString()
newZealandDate.toString()
utcDate.toString()

japanDate2.toString()
localDate.toString()

// Or get date components
unalaskaDate.hour
unalaskaDate.day
unalaskaDate.month
unalaskaDate.year

dubaiDate.hour
dubaiDate.day
dubaiDate.month
dubaiDate.year

magadanDate.hour
magadanDate.day
magadanDate.month
magadanDate.year


//: #### Equations
//: DateInRegion conforms to the Equatable protocol. I.e. you can compare with == for equality.
let newDate2 = DateInRegion(fromDate: newDate)
let newDate3 = DateInRegion(fromDate: newDate, hour: 9)!
newDate == newDate
newDate == newDate2
newDate == newDate3

//: For equal date values, you should use x.isEqualToDate(y) note that this compares the moment not the region

//: #### Comparisons
//: DateInRegion conforms to the Comparable protocol. I.e. you can compare with <. <=, ==, >=, >
newDate > newDate2
newDate >= newDate2
newDate == newDate2
newDate != newDate2
newDate <= newDate2
newDate < newDate2

//: Mind that comparisons takes the absolute time from the date property into account.
//: regions (calendars, time zones, locales, have no effect on the comparison results.
let date1 = DateInRegion(year: 2000, month: 1, day: 1, hour: 14, region: utc)!
let date2 = (date1 + 1.hours)!

//: date1 = 14:00 UTC
//: date2 = 15:00 UTC
date1 > date2
date1 < date2

let indiaDate1 = DateInRegion(fromDate: date1, region: india)

//: indiaDate1 = 19:30 IST
//: date1 = 14:00 UTC
//: date2 = 9:00 CST
indiaDate1 > date2
indiaDate1 < date2

indiaDate1.isEqualToDate(date1)

//: QED: same outcome!


//: #### Collections

//: Use as a key in a dictionary
var birthdays = [DateInRegion: String]()
birthdays[DateInRegion(year: 1997, month: 5, day: 7)!] = "Jerry"
birthdays[DateInRegion(year: 1999, month: 12, day: 14)!] = "Ken"
birthdays[DateInRegion(year: 1990, month: 12, day: 5)!] = "Sinterklaas"
birthdays.sort({ (a: (date: DateInRegion, String), b: (date: DateInRegion, String)) -> Bool in
return a.date < b.date
})



//: #### Display & string conversion
//: DateInRegion conforms to the ConvertString protocol
chinaDate.description
chinaDate.toString()

// Various string styles
now.toString()!
now.toString(.LongStyle)!
now.toString(.MediumStyle)!
now.toString(.ShortStyle)!
now.toString(dateStyle: .ShortStyle)!
now.toString(timeStyle: .MediumStyle)!
now.toString(dateStyle: .LongStyle, timeStyle: .ShortStyle)!
now.toString("YYYY")!
now.toString("yy-mm-dd")!

使用方法

要运行示例项目,请克隆仓库,然后首先从 Example 目录运行 pod install

要求

需要 iOS 9。测试代码需要 Quick 和 Nimble 实现。您可以通过在 Examples 目录中运行 pod install 来实现。

安装

手动

使用 git 删除并添加 DateInRegion.swift 至您的项目。

git clone https://github.com/Hout/DateInRegion.git

设计决策

在设置库时,我做出了以下决策。我欢迎对这些决策提供反馈。

决策 理由
DateInRegion的主要功能是在地区之间切换和转换日期。不是为了处理本地地区的日期,尽管它可以用来实现这一点。 这正是我所需要的 :-)
DateInRegion不是NSDate的扩展 一般来说,NSDate的扩展代表各种格式的当前日期。扩展还限制了类,因为你不能添加存储属性。后者我需要存储区域数据(日历、时区和地区)。Cocoapods提供了大量的NSDate扩展,例如SwiftDate
不要包括从字符串的初始化器 世界上太复杂了,有太多的记法方式。它相较于现成的便捷初始化器几乎没有多少好处。
不要尝试模仿NSDateFormatterNSDateComponents等类中的所有属性和函数。例如,NSDateFormatterlocalizedStringFromDateweekdaySymbols 有时直接使用DateInRegiondate属性会更简单。
等式==不仅针对日期值,而是针对整个对象 类似于 NSObject 的规定;尽管对象不需要是同一个实例,但它们必须包含相等的属性

作者

Jeroen Houtzager,请通过 GitHub 联系我

合作

如果你想做出贡献

  • 分支
  • 发送拉取请求
  • 提交问题
  • 挑战设计决策
  • 挑战编码
  • 挑战任何事!

以下库和作者启发了这个代码

  • SwiftDate 来自 Daniele Margutti。如果你在寻找一个简洁的 Swift NSDate 扩展,我推荐这个。

许可证

DateInRegion 可在 MIT 许可证下获得。有关更多信息,请参阅 LICENSE 文件。