DateToolsSwift 5.0.0

DateToolsSwift 5.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2020年1月
SPM支持 SPM

Matt YorkMatt York维护。



  • Matthew York

Banner

DateTools

DateTools被编写用来精简iOS中的日期和时间处理。DateTools从其他语言中的类和概念中获得了灵感,特别是DateTime结构和Time Period Library。通过这些类和其他类,DateTools消除了访问日期组件所需的样板代码,处理了更多的日期比较,并为时间周期及其集合等全新概念奠定了基础。

Build Status CocoaPods CocoaPods

特惠于

Yahoo! Livetext 我的迪士尼体验 ALDI Guidebook YouTube 音乐 可汗学院

捐赠

bitcoin: 17ZEBFw5peuoUwYaEJeGkpoJwP1htViLUY

安装

CocoaPods

Swift

pod 'DateToolsSwift'

Objective-C (旧版)

pod 'DateTools'

手动安装

所需的所有DateTools类都位于本存储库根目录下的DateTools文件夹中。以下列出了它们:

Swift(位于DateToolsSwift/DateTools中)

  • Constants.swift
  • Date+Bundle.swift
  • Date+Comparators.swift
  • Date+Components.swift
  • Date+Format.swift
  • Date+Inits.swift
  • Date+Manipulations.swift
  • Date+TimeAgo.swift
  • DateTools.bundle
  • Enums.swift
  • Integer.DateTools.swift
  • TimeChunk.swift
  • TimePeriod.swift
  • TimePeriodChain.swift
  • TimePeriodCollection.swift
  • TimePeriodGroup.swift

Objective-C(位于DateTools/DateTools中)

  • DateTools.h
  • NSDate+DateTools.{h,m}
  • DTConstants.h
  • DTError.{h,m}
  • DTTimePeriod.{h,m}
  • DTTimePeriodGroup.{h,m}
  • DTTimePeriodCollection.{h,m}
  • DTTimePeriodChain.{h,m}

如果您想支持国际化或要使用"时间前"功能,则需要以下程序包。您可以在"项目"菜单下的"信息"下的"本地化"子标题下添加本地化内容。

  • DateTools.bundle

DateTools.h包含所有其他文件的头文件。如果您想链接到整个框架,请导入此头文件。

目录

DateTools

完整代码文档可在此处找到:http://cocoadocs.org/docsets/DateToolsSwift/2.0.0/

DateTools的使命之一是使Date更加完整。有很多其他语言允许直接通过它们的日期类访问关于日期的信息,但Date(遗憾的是)做不到这一点。它只能通过timeIntervalSince...方法使用Unix时间偏移量安全地工作,并且对于日历无关紧要。但这不是我们总是想要做的。有时,我们希望在更抽象的级别上根据日期组件(如年、月、日等)来处理日期。这就是DateTools的作用。

时间差

没有任何日期库能够完整,没有快速根据日期与现在的时间差快速生成一个基于NSString的功能。DateTools为您解决这一需求。这些“时间差”字符串有长和短两种形式,后者与Twitter非常相似。您可以这样获取这些字符串:

let timeAgoDate = 2.days.earlier
print("Time Ago: ", timeAgoDate.timeAgoSinceNow)
print("Time Ago: ", timeAgoDate.shortTimeAgoSinceNow)

//Output:
//Time Ago: 2 days ago
//Time Ago: 2d

假设您已将本地化添加到项目中,DateTools目前支持以下语言:

  • ar (阿拉伯语)
  • bg (保加利亚语)
  • ca (加泰罗尼亚语)
  • zh_Hans (简体中文)
  • zh_Hant (繁体中文)
  • cs (捷克语)
  • da (丹麦语)
  • nl (荷兰语)
  • en (英语)
  • fi (芬兰语)
  • fr (法语)
  • de (德语)
  • gre (希腊语)
  • gu (古吉拉特语)
  • he (希伯来语)
  • hi (印地语)
  • hu (匈牙利语)
  • is (冰岛语)
  • id (印度尼西亚语)
  • it (意大利语)
  • ja (日语)
  • ko (韩语)
  • lv (拉脱维亚语)
  • ms (马来语)
  • nb (挪威语)
  • pl (波兰语)
  • pt (葡萄牙语)
  • ro (罗马尼亚语)
  • ru (俄语)
  • sl (斯洛文尼亚语)
  • es (西班牙语)
  • sv (瑞典语)
  • th (泰语)
  • tr (土耳其语)
  • uk (乌克兰语)
  • vi (越南语)
  • cy (威尔士语)
  • hr (克罗地亚语)

如果您知道这里没有列出的语言,请考虑提交翻译。有关语言本地化代码

本项目是由用户驱动的(像您这样的人)。合并请求比问题(合并或拒绝)关闭得更快。

感谢Kevin Lawler对NSDate+TimeAgo的贡献,该贡献已正式并入此库。

日期组件

从Date获取日期组件有许多样板代码。您需要设置日历,使用所需的标志来设置所需的组件,最后从日历中提取出来。

使用DateTools,这

//Create calendar
let calendar = Calendar(identifier: .gregorian)
let dateComponents = calendar.dateComponents(Set<Calendar.Component>([.month,.year]), from: Date())
        
//Get components
let year = dateComponents.year!
let month = dateComponents.month!

...变为这

let year = Date().year
let month = Date().month

日期编辑

DateTools中的日期编辑方法可以通过添加和减去日期组件来轻松地将日期向前或向后移动。例如,如果您想从一个给定日期算起一年后的日期,只需调用dateByAddingYears方法。

使用DateTools,这

//Create calendar
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:[NSDate defaultCalendar]];
NSDateComponents *components = [[NSDateComponents alloc] init];

//Make changes
[components setYear:1];

//Get new date with updated year
NSDate *newDate = [calendar dateByAddingComponents:components toDate:date options:0];

...变为这

NSDate *newDate = [date dateByAddingYears:1];

通过dateBySubtractingYears也完全支持日期组件的减法。

日期比较

DateTools 类别的另一个任务是大大提高日期比较的灵活性。Date 提供了四个基本方法:

  • isEqualToDate
  • earlierDate
  • laterDate
  • compare

earlierDate:laterDate: 很好,但如果有布尔响应来帮助构建逻辑会更好;轻松地问 "这个日期比那个日期早吗?"。DateTools 提供了一组代理方法,同时还提供了一些其他方法来增加灵活性。新方法包括:

  • isEarlierThan
  • isEarlierThanOrEqualTo
  • isLaterThan
  • isLaterThanOrEqualTo

这些方法非常适合以布尔方式比较日期,但如果我们想比较日期并返回一些有关它们之间差距的有意义的信息怎么办?Date 提供了两个方法 timeIntervalSinceDate:timeIntervalSinceNow,这两个方法返回一个表示两个日期之间秒数的 double 偏移量。这很好,但有时候想知道两个日期之间有多少年或多少天。对于此,DateTools 返回到始终可靠的 NSCalendar,并为您抽象出所有必要的代码。

使用 Date Tools,这

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:[NSDate defaultCalendar]];
NSDate *earliest = [firstDate earlierDate:secondDate];
NSDate *latest = (secondDate == firstDate) ? secondDate : firstDate;
NSInteger multiplier = (secondDate == firstDate) ? -1 : 1;
NSDateComponents *components = [calendar components:allCalendarUnitFlags fromDate:earliest toDate:latest options:0];
NSInteger yearsApart = multiplier*(components.month + 12*components.year);

..变成这样

NSInteger yearsApart = [firstDate yearsFrom:secondDate];

本类别中包括的比较方法有:

  • yearsFrom:yearsUntil:yearsAgo:yearsEarlierThan:yearsLaterThan:
  • monthsFrom:monthsUntil:monthsAgo:monthsEarlierThan:monthsLaterThan:
  • weeksFrom:weeksUntil:weeksAgo:weeksEarlierThan:weeksLaterThan:
  • daysFrom:daysUntil:daysAgo:daysEarlierThan:daysLaterThan:
  • hoursFrom:hoursUntil:hoursAgo:hoursEarlierThan:hoursLaterThan:
  • minutesFrom:minutesUntil:minutesAgo:minutesEarlierThan:minutesLaterThan:
  • secondsFrom:secondsUntil:secondsAgo:secondsEarlierThan:secondsLaterThan:

格式化日期字符串

为了好玩,DateTools 提供了一些方便的方法来快速从日期创建字符串。这两个方法是 formattedDateWithStyle:formattedDateWithFormat:。除非在方法参数中指定,否则使用当前区域设置。再次强调,只是为了好玩。

时间段

日期很重要,但现实世界比这稍微离散一些。生活是由时间间隔构成的,比如下午的约会或为期一周的假期。在DateTools中,时间段由TimePeriod类表示,并附带一套初始化、操作和比较方法,使得使用它们变得轻松。

初始化

时间段由一个开始日期和一个结束日期组成。要初始化一个时间段,请调用init函数。

DTTimePeriod *timePeriod = [[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];

或者,如果您想创建一个已知长度且开始或结束于特定时间的时间段,可以尝试其他一些init方法。下面的方法,例如,创建一个从当前时间开始,长度正好为5小时的时间段。

DTTimePeriod *timePeriod = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeHour amount:5 startingAt:[NSDate date]];

时间段信息

已扩展一系列方法来提供有关TimePeriod实例的信息。以下列出了一些:

  • hasStartDate - 如果时间段有开始日期,则返回true
  • hasEndDate - 如果时间段有结束日期,则返回true
  • isMoment - 如果时间段开始和结束日期相同,则返回true
  • durationIn.... - 以请求的单位返回时间段长度

操作

时间段也可以进行操作。可以提前或推迟,也可以扩展或缩短。

移动

当时间段被移动时,开始日期和结束日期都会根据请求的数量提前或推迟。要提前移动时间段,请调用shiftEarlierWithSize:amount:,要推迟移动时间段,请调用shiftLaterWithSize:amount:。此字段作为乘数,就像在上面的初始化方法中一样。

拉长/缩短

当时间段被拉长或缩短时,它会锚定时间段的其中一个日期,然后改变另一个日期。还有一个选项可以锚定时间段的中心点,改变开始和结束日期。

以下是一个时间段拉长的示例:

DTTimePeriod *timePeriod  = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeMinute endingAt:[NSDate date]];
[timePeriod lengthenWithAnchorDate:DTTimePeriodAnchorEnd size:DTTimePeriodSizeMinute amount:1];

这将把持续1分钟的时间段扩展到2分钟。保持“现在”的结束日期不变,只将开始日期提前1分钟。

关系

可能会出现需要的时候,例如你在制作日程安排应用时,你可能想知道两个时间段之间如何相互关系。它们是否相同?一个是否包含在另一个中?你可以使用TimePeriod的关联方法提出所有这些问题。

以下是两个时间段之间所有可能关系的图表:时间段

一些方法已经被扩展以检查基本关系。以下列出它们:

  • isEqualToPeriod
  • isInside
  • contains
  • overlapsWith
  • intersects

你还可以使用以下方法检查官方关系(如图表所示):

-(DTTimePeriodRelation)relationToPeriod:(DTTimePeriod *)period;

TimePeriodRelation枚举中已列举了所有可能关系。

要更好地理解时间段之间的关系,请查看示例应用中的“时间段”标签页。在这里,你可以滑动几个时间段,并观察它们之间关系的变化。

TimePeriods

时间段组

时间段组是在DateTools中对日期和时间的最终抽象。在这里,时间段被收集和组织成有用的东西。时间段组有两种主要类型,TimePeriodCollectionTimePeriodChain。从高层次来看,你可以将集合看作是一个松散的组,其中可以发生重叠,而链则是更线性、紧密的组,其中不允许重叠。

集合和链的操作就像NSArray一样。你可以像在数组中一样向它们添加、插入和删除TimePeriod对象。区别在于这些周期在底层是如何处理的。

时间段集合

时间段集合是一组松散的时间段。除非你决定排序,否则它们是无组织的,并具有自己的特征,如从时间段中提取的StartDate和EndDate。时间段集合允许其集合中的时间段发生重叠。

TimePeriodCollections

要创建一个新的集合,请按如下方式调用类方法:

//Create collection
DTTimePeriodCollection *collection = [DTTimePeriodCollection collection];

//Create a few time periods
 DTTimePeriod *firstPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2014 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"]];
    DTTimePeriod *secondPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2016 11 05 18:15:12.000"]];

//Add time periods to the colleciton
[collection addTimePeriod:firstPeriod];
[collection addTimePeriod:secondPeriod];

//Retreive collection items
DTTimePeriod *firstPeriod = collection[0];

排序 在集合中对时间段进行排序很容易,只需调用其中一个排序方法。总共有三个排序选项,如下所示:

  • 开始日期 - sortByStartAscendingsortByStartDescending
  • 结束日期 - sortByEndAscendingsortByEndDescending
  • 时间段时长 - sortByDurationAscendingsortByDurationDescending

操作 还可以检查 Date 或 TimePeriod 与集合的关系。例如,如果您想查看与特定日期相交的所有时间段,可以调用 periodsIntersectedByDate: 方法。结果是一个新的 TimePeriodCollection,其中包含所有与给定日期相交的时间段。还有许多其他方法可以尝试,包括两个集合之间的完全相等检查。

TimePeriodCollectionOperations

时间段链

时间段链是一组紧密相关的时段。它们始终按开始和结束日期组织,并且有自己独特的特征,如 StartDate 和 EndDate,这些日期是从时间段内推断出来的。时间段链在其时间段集内不允许重叠。此类型组非常适合用于建模连续会议或预约等日程。

TimePeriodChains

要创建一个新链,请按如下方式调用类方法

//Create chain
DTTimePeriodChain *chain = [DTTimePeriodChain chain];

//Create a few time periods
 DTTimePeriod *firstPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2014 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"]];
DTTimePeriod *secondPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2016 11 05 18:15:12.000"]];

//Add test periods
[chain addTimePeriod:firstPeriod];
[chain addTimePeriod:secondPeriod];

//Retreive chain items
DTTimePeriod *firstPeriod = chain[0];

将任何日期添加到时间链中时,它会保留其持续时间,但会修改其 StartDate 以与其链中最后一个周期的 EndDate 相同。这有助于保持链的时间段的紧密耦合结构。除了索引 0 之外的所有插入(除了索引 0 之外的插入)将插入索引后的日期位移动新时间段的持续时间,而索引在插入索引之前保持不变。索引 0 的插入将集合的起始日期位移动新时间段的持续时间。下面可以查看完整的操作列表。

操作 如集合一样,链有相等检查和能够提前和延后的能力。下面是其他操作的简要列表。

TimePeriodChainOperations

文档

所有方法和变量都已记录,并且可以像 SDK 类一样进行 option+click 检查。这包括方法的说明以及它们的输入和输出参数。如果您觉得文档混乱或具有误导性,请提出问题,我们将修复它!

单元测试

对库中的所有主要类进行了单元测试,以确保质量。您可以在库顶部的“Tests”文件夹中找到这些测试。总共有超过 300 个测试用例!

如果您发现任何测试用例不完整,请打开一个问题,这样我们就可以修复它。

连续集成测试由Travis CI执行:构建状态

致谢

感谢Grayson Webster帮助重新构思Swift中的DateTools,并迅速编写必要的代码!

感谢Kevin Lawler对�始版本的NSDate+TimeAgo的工作,这为DateTools的时间Ago方法奠定了基础。您可以在这里找到这个伟大的项目。

还要感谢.NET团队对其DateTime类的贡献,以及感谢Jani Giannoudis对ITimePeriod的工作。

图片最初通过itenso.com和代码项目发布

我还要感谢全能的上帝,通过上帝一切存在并进行其中。 使徒行传 17:28

许可协议

MIT许可协议(MIT)

版权所有 (c) 2014 Matthew York

特此免费许可任何人,以免费的方式,获取此软件及其相关文档文件(统称为“软件”)的副本,不受限制地处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件的副本,以及允许任何人将软件提供给他人以实现上述目的,前提是遵守以下条件:

上边的版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件按现状提供,不提供任何形式的保证,无论是明示的、暗示的还是其他形式的,包括但不限于适销性、适用性与非侵权性保证。在任何事件中,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是基于合同、侵权或其他原因产生的,或者与软件或使用或操作软件有关。