GrandTime--操作iOS的时间更简单

作者: 黑暗中的孤影 | 来源:发表于2016-07-19 13:10 被阅读733次
例行上图

有一个多月没有更新简书了,因为工作确实比较忙,天天加班。现在APP已经上线,是时侯继续我的写作之旅了。这次项目里面会进行大量的日期时间操作。比如获取某日期年月日,时分。两个日期的比较。设置某个日期的时间等操作。总之这次开发过程中不友好NSDate和其相关类的API让我感到不爽,感觉iOS原生的日期类非常不好用。于是我便萌生了自己写一个关于操作NSDate的类的想法,因以我以前是用C#,感觉C#的日期时间类比较优雅,我便参考它写了个iOS的DateTime,今天我便分享给大家。

iOS对日期和时间的操作的不足

NSDate是iOS表示日期时间的核心类。但是它也只能表示时间,如果需要格式化输出,需要使用到NSDateFormatter类,而如果需要取出里面的年月日和时分秒,则需要用到NSDateComponentsNSCalendar。相信每一位iOS开发者都会掌握这些类的使用,这里就不写示例代码了。虽然职责分离是一种好的设计,但是需要你大量对日期时间的比较,格式化输出等操作时,使用这些类来非常繁琐,要写很多的重复的代码,影响了开发效率。GrandTime正是解决这个问题而生的。

GrandTime组成

GrandTime由三个类组成:DateTime,TimeSpanGrandTimerDateTime是最核心的类,封装了NSDateNSDateComponents。把年月日时分秒的操作变得十分简单方便。而TimeSpan是一段时间间隔,相当于NSTimeInterval,同时还封装了很多功能。而GrandTimer是一个会自动停止的弱Timer,并且提供了Block来方便调用。下面我一个一个来介绍怎么使用。

DateTime

DateTime类封装了常见的日期时间操作。它提供了如下8个构造函数

DateTime的构造函数
相信这8个构造函数可以满足绝大部分的使用场景。里面有两个需要说明一下,tick在里面是指毫秒,而timestampUnix时间戳。默认的无参构造函数和NSDate一样,都是使用当前时间。
下面看看代码
//正面看看构造函数
let a = DateTime() //直接初始化
print(a)
let c = DateTime(date: NSDate(timeInterval: 3600, sinceDate: NSDate())) //使用NSDate初始化
print(c)
let e = DateTime(tick: 1000000) //使用Tick初始化  从1970年开始
print(e)
let f = DateTime(tickSinceNow: 60000) //使用Tick初始化  从现在年开始
print(f)
let g = DateTime(timestamp: 100000)//使用Stamp初始化
print(g)
let h = DateTime(year: 2008, month: 2, day: 29) //使用年月日初始化
print(h)
let i = DateTime(year: 2016, month: 12, day: 12, hour: 11, minute: 44, second: 12, millisecond: 111)!//使用年月日时分秒毫秒初始化
print(i)
打印结果:
2016-07-18 15:04:37:779
2016-07-18 16:04:37:779
Optional(1970-01-01 08:16:40:000)//注意里面存在初始化失败这种情况,我没有直接抛出异常,而是返回可选值。
Optional(2016-07-18 15:05:37:780)
Optional(1970-01-02 11:46:40:000)
Optional(2008-02-29 00:00:00:000)
2016-12-12 11:44:12:000

我为DateTime提供了操作符重载

let timeSpanOneMinute = TimeSpan.fromMinuts(1)   //声明一个一分钟的TimeSpan
let dToOneMinuteBefore = a - timeSpanOneMinute      // 一分钟前
print("一分钟前\(dToOneMinuteBefore)")
let dToOneMinuteAfter = a + timeSpanOneMinute // 一分钟后
print("一分钟后\(dToOneMinuteAfter)")
        
  //两个DateTime相减生成一个TimeSpan
let span = c - a
        
print("a和c相差一小时\(span)")
print("a>c:\(a>c)")
print("a<c:\(a<c)")
打印结果:
一分钟前2016-07-18 15:14:10:274
一分钟后2016-07-18 15:16:10:274
a和c相差一小时Optional(1:00:00:000)
a>c:false
a<c:true

DateTime也提供了一系列Add方法,可以对自身操作。改变自己的时间值。

DateTime的Add系列方法
a.addYears(1)   //加一年
print("add Years:\(a)")
a.addMonth(1)   // 加 一个月
print("add addMonth:\(a)")
a.addDays(1)    // 加一天
print("add addDays:\(a)")
a.addHours(1)   // 加一个小时
print("add addHours:\(a)")
a.addMinutes(1) // 加一分钟
print("add addMinutes:\(a)")
a.addSeconds(1) // 加一秒
print("add addSeconds:\(a)")
打印结果:
add Years:2017-07-18 17:20:09:080
add addMonth:2017-08-18 17:20:09:080
add addDays:2017-08-19 17:20:09:080
add addHours:2017-08-19 18:20:09:080
add addMinutes:2017-08-19 18:21:09:080
add addSeconds:2017-08-19 18:21:10:080

使用DateTime来获取日期时间的每个部分也是非常简单,同时也支持单独设值

print("获取i的各部分:year:\(i.year),   month:\(i.month),   day:\(i.day),   hour:\(i.hour),   minute:\(i.minute),   second:\(i.second),   minute:\(i.minute),   ticks:\(i.ticks),   ")
        
//还可以直接设置各部分
i.year = 2015
i.month = 1
i.day = 12
i.hour = 12
i.minute = 23
i.second = 12
i.millisecond = 555
print("再次获取i的各部分:year:\(i.year),   month:\(i.month),   day:\(i.day),   hour:\(i.hour),   minute:\(i.minute),   second:\(i.second),   minute:\(i.minute),   ticks:\(i.ticks),   ")
//打印结果
获取i的各部分:year:2016,   month:12,   day:12,   hour:11,   minute:44,   second:12,   minute:44,   ticks:1481514252000,   
再次获取i的各部分:year:2015,   month:1,   day:12,   hour:12,   minute:23,   second:12,   minute:23,   ticks:1421036592555,   


//获取季度和星期相关数据
print("星期几:\(i.weekDay)")
print("第几季度:\(i.quarter)")
print("一年的第几周:\(i.weekOfYear)")
print("一个月的第几周:\(i.weekOfMonth)")
print("一年的第几天:\(i.dayOfYear)")
//打印结果
星期几:Wendesday
第几季度:0
一年的第几周:3
一个月的第几周:3
一年的第几天:43

最后就是格式化输出了,DateTime使用了一个单例的NSDateFormatter,这样可以防止不必要的频繁实例化NSDateFormatter。下面看看输出

print("获取日期部分\(i.dateString)")  //获取日期部分
print("获取时间部分\(i.timeString)")     //获取时间部分  
print("默认格式\(i.format())")
print("自定义格式\(i.format("yyyy年MM月dd日#EEEE"))")
print("各种输出style的原生的一样")
print("LongStyle: \(i.format(.ShortStyle, timeFormat: .ShortStyle))")
print("LongStyle: \(i.format(.MediumStyle, timeFormat: .MediumStyle))")
print("LongStyle: \(i.format(.LongStyle, timeFormat: .LongStyle))")
print("LongStyle: \(i.format(.FullStyle, timeFormat: .FullStyle))")

i.local = NSLocale(localeIdentifier: "en_US")

print("把地区设为US"),
print("LongStyle: \(i.format(.ShortStyle, timeFormat: .ShortStyle))")
print("LongStyle: \(i.format(.MediumStyle, timeFormat: .MediumStyle))")
print("LongStyle: \(i.format(.LongStyle, timeFormat: .LongStyle))")
print("LongStyle: \(i.format(.FullStyle, timeFormat: .FullStyle))")

//打印结果
获取日期部分2015-01-12
获取时间部分12:23:12
默认格式2015-01-12 12:23:12:555
自定义格式2015年01月12日#Monday
各种输出style的原生的一样
LongStyle: 15/1/12 下午12:23
LongStyle: 2015年1月12日 下午12:23:12
LongStyle: 2015年1月12日 GMT+8 下午12:23:12
LongStyle: 2015年1月12日 星期一 中国标准时间 下午12:23:12
把地区设为US
LongStyle: 1/12/15, 12:23 PM
LongStyle: Jan 12, 2015, 12:23:12 PM
LongStyle: January 12, 2015 at 12:23:12 PM GMT+8
LongStyle: Monday, January 12, 2015 at 12:23:12 PM China Standard Time

DateTime的用法在上面的代码基本可以全部找到。更多的用法请参考原代码或者API。可见,使用DateTime还操作时间还是很方便的。

TimeSpan

同样,为了更好地使用时间间隔,我写了TimeSpan来专门处理时间间隔。TimeSpan类比较简单一点,下面直接上代码


      //先看看构造函数
        
let o = TimeSpan()                                     //直接初始化
print(o)
let p = TimeSpan(days: 1, hours: 0, minutes: 11, seconds: 31)   //使用天,小时,分钟,秒来初始化
print(p)
let q = TimeSpan(days: 20, hours: 11, minutes: 39, seconds: 21, milliseconds: 111)!   //使用天,小时,分钟,秒还有来初始化
print(q)
let r = TimeSpan(ticks: 9826127)   //使用tick来初始化
print(r)
        
//打印结果
0:00:00:000 //全是0
Optional(1 0:11:31:000) //1天11分钟31秒
20 11:39:21:111 //20天11小时39分钟21秒111毫秒
2:43:46:127 //2小时43分钟46秒127毫秒

TimeSpan的构造函数不多,也比较简单。里面最大的时间间隔单位是天这个单位。因为天可以一直累加,所以也足够用了。同样,使用from系列静态函数也可以自己想要的时间间隔,

From系列静态函数
从图中可以看出,很多函数所传递的变量是Double类型的, 也就是说,可以给它传小数值。下面看看代码吧
//使用from 函数
print("使用from函数")
var s = TimeSpan.fromDays(1) //一天
print(s)
s = TimeSpan.fromHours(2.5) //2.5小时
print(s)
s = TimeSpan.fromMinuts(89.2)//89.2分钟
print(s)
s = TimeSpan.fromSeconds(134)//134秒
print(s)
s = TimeSpan.fromTicks(123123123)//123123123 tick
//打印结果
使用from函数
1 0:00:00:000
2:30:00:000
1:29:12:000
0:02:14:000
1 10:12:03:123

可以单独取和设定某个属性

//下面获取部分
print("获取i的各部分:  day:\(q.days),   hour:\(q.hours),   minute:\(q.minutes),   second:\(q.seconds),   minute:\(q.milliseconds),   ticks:\(q.ticks),   ")
//获取计算的总体部分
print("获取i的各部分:  totalDays:\(q.totalDays),   totalHours:\(q.totalHours),   totalMinutes:\(q.totalMinutes),   second:\(q.totalSeconds)")
//单独设定属性
q.days = 4
q.hours = 22
q.minutes = 12
q.seconds = 32
q.milliseconds = 343
print("获取i的各部分:  day:\(q.days),   hour:\(q.hours),   minute:\(q.minutes),   second:\(q.seconds),   minute:\(q.milliseconds),   ticks:\(q.ticks),   ")
print("获取i的各部分:  totalDays:\(q.totalDays),   totalHours:\(q.totalHours),   totalMinutes:\(q.totalMinutes),   second:\(q.totalSeconds)")

//打印结果
获取i的各部分:  day:20,   hour:11,   minute:39,   second:21,   minute:111,   ticks:1769961111,   
获取i的各部分:  totalDays:20.4856610069444,   totalHours:491.655864166667,   totalMinutes:29499.35185,   second:1769961.111
获取i的各部分:  day:4,   hour:22,   minute:12,   second:32,   minute:343,   ticks:426239657,   
获取i的各部分:  totalDays:4.93332936342593,   totalHours:118.399904722222,   totalMinutes:7103.99428333333,   second:426239.657

DateTime一样,重载了运算符号来实现TimeSpan之间也的加减操作,

print("下面看加减")
s = s.add(r)  //可以用这个加
print(s)
        
s = s.subtract(r)  //可以用这个减
print(s)
print("运算符+ - 也一样")
s = s + r
print(s)
s = s - r
print(s)
打印结果
下面看加减
1 12:55:49:250
1 10:12:03:123
运算符+ - 也一样
1 12:55:49:250
1 10:12:03:123

OK, 上面就是DateTimeTimeSpan的各种用法,相信它们可以满足大部分项目的需求,如果不够,自己也可以写扩展来实现。

GrandTime还提供了一个计时器GrandTimer。和NSTimer不一样,GrandTimer不会强引用当前类。所以不会出现NSTimer那种只要不调用valifdate()方法就会在内存里一直运行这种情况。使用GrandTimer非常简单,直接使用其静态方法即可

weak var weakSelf = self
//使用者要注意,这个timer本身是weak的,所以需要一个外部变量来强引用, 不然出这代码区域,就会被内存回收导致计时器不能运行
//如果要让timer正确地释放内存,那么要使用weakself
 timer =  GrandTimer.every(TimeSpan.fromSeconds(1)) {
      weakSelf!.seco2 = weakSelf!.seco2 + 1
      weakSelf!.lblTimer.text = "\(weakSelf!.seco2)"
 }
//如果要暂停
  timer?.invalidate()
// 重写了该ViewController的deinit
    deinit{
        print("\(self.dynamicType)) the view deinit which means the timer release in the viewcontrollre")
    }
   //如果pop该ViewController出去,这个时侯会打印
TimerViewController) the view deinit which means the timer release in the viewcontrollre
//说明该View已经正确地被内存释放了

GrandTimer也提供了一个selector版本,不过需要自己提供一个线程,这种用法用NSTimer很类似。

let dispatch = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT)
timer = GrandTimer.scheduleTimerWithTimeSpan(TimeSpan.fromSeconds(1), target: self, sel: #selector(TimerViewController.tick), userInfo: nil, repeats: true, dispatchQueue: dispatch)
        timer?.fire()

以上就是GrandTime的所有功能的展示的,我已经将这个项目加入了Cocoapods。 使用起来非常简单,直接pod‘GrandTime’就可以啦,如果你不想用Cocoapods,那么也可以将里面的文件直接拖到项目里面。Git地址:GrandTime。 如果你们喜欢的话,麻烦给个Star。

相关文章

  • GrandTime--操作iOS的时间更简单

    有一个多月没有更新简书了,因为工作确实比较忙,天天加班。现在APP已经上线,是时侯继续我的写作之旅了。这次项目里面...

  • 基于AFNetworking的iOS文件下载框架

    接着上一篇 简单易用的iOS数据库操作框架 文章,这里简单介绍下基于 AFNetworking 的iOS文件下载框...

  • iOS时间操作

    1.获取当前年份月份 2.获取系统时间 时间格式@"yyyy-MM-dd HH:mm:ss"注意月份和小时MM和H...

  • UIImage 处理(I)

    参考资料:iOS绘图 - UIImage的一些简单操作iOS 图片圆角处理及各种“角”的解决方案

  • 文案训练营第一周作业

    1.现在使用的苹果手机,之所以会选择这个是因为IOS系统相比于其他系统更符合我的使用习惯,操作简单但功能强大 2....

  • iOS 几种简单的延迟操作

    最近在做项目中碰到需要做个延时操作,于是把这个几个简单方法记录下来以便以后使用方便; 如果有更好的方法欢迎添加一起...

  • 多线程之NSOperation简介

    在iOS开发中,为了提升用户体验,我们通常会将操作耗时的操作放在主线程之外的线程进行处理。对于正常的简单操作,我们...

  • iOS 原生与WKWebView交互

    GCWKWebViewJSBridge 让 iOS 原生与WKWebView交互更简单[https://www.j...

  • Mac os - 文件操作坑点

    做文件操作的时候必须设置以下权限: 然后文件操作就更iOS里面一样了。 使用NSFileManager 需要注意,...

  • iOS热修复简单操作

    首先把官方地址亮出来官网,使用规则一目了然,很详细,大赞的使用。我只是想以自己的理解方式做个笔记。 热修复的作用:...

网友评论

  • 白水灬煮一切:楼主学了那么多语言,目前我也学了几门语言了,想一下,这个语言两月不用就基本忘记了不会写了,你是怎么保持几门语言的运用的?
    黑暗中的孤影:@白水灬煮一切 我也是偷懒了好几个月了,也有很多语言不会用了。所以还是多找事做才行
  • XLsn0w:吃驚, 楼主目前是swift开发? 还是混编
    黑暗中的孤影:@XLsn0w 老项目做修改其实也是可以用swift写的,新项目直接用swift就行了, 如果 你们用OC习惯了也没学过其他语言的话可能会有点难适应,但是我会用很多语言所以很快就能上手Swift
    XLsn0w:@黑暗中的孤影 吃惊, OC转过来的? 还是直接Swift
    黑暗中的孤影:@XLsn0w 90%是swift了,除非有必要,不会再用OC的
  • a4a8de24c022:老fu,我来看你啦 :+1:
  • o1xhack:可以,收藏备用!

本文标题:GrandTime--操作iOS的时间更简单

本文链接:https://www.haomeiwen.com/subject/tsqujttx.html