处理时间和日期是软件开发中很常见的操作,几乎所有的编程语言都提供了对应的 API 来方便开发者对时间日期进行处理,Swift 也不例外,比如 DateFormatter ,使用它你可以将任意 Date 转换成自定义格式的文本字符串。
——但是, DateFormatter 很慢!它是一个非常耗时的操作,从创建到使用,每一步都占用了大量的时间,如果不是必要,几乎所有的高级程序员都不会建议你使用这个对象。
老生常谈的 C 语言
Swift 是可以直接调用 C 语言的,除了 Foundation 里的 DateFormatter ,其实你还可以选择C strftime ,它比起前者少了不少高级功能,但如果你的需求仅仅是格式化输出时间,那 strftime 将非常好用。
优点(相对 DateFormatter 来说):
- 速度快,同样的操作 DateFormatter 要 1.4 ms 完成,而 strftime 只需要0.2 ms,甚至更快!
- 内存占用小,由于没有 DateFormatter 那样复杂的功能,非常节约内存资源。
缺点:
- 代码上可能没 DateFormatter 那么容易操作,毕竟是 C 语言 API,即使是用 Swift 来调用,也会非常痛苦;
- 不支持时区,最多能获取当前时区和 utc 时区;
- 格式化操作比较少,常用的都有,但如果要 DateFormatter 那么多的格式,可能就需要你自己动手处理了。
代码
好在,复杂的代码操作也只需要一次性封装即可,通常与服务器通讯或者为用户显示时间,也不需要复杂的时区操作,所以绝大部分的业务场景是可以用 strftime 代替 DateFormatter 的。
我们写一个 Date 的 extension 来封装这个操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
extension Date { func formattedTime(format: String) -> String? { let resultSize = format.count + 200 var result = [Int8](repeating: 0, count: resultSize) var currentTime = time(nil) var time = localtime(¤tTime).pointee guard strftime(&result, resultSize, format, &time) != 0 else { return nil } return String(cString: result, encoding: .utf8) } } |
这里有些困难的地方在于需要使用 C 指针,但 Swift 又把指针隐藏的很好,总之,我们使用一个 Int8 的数组来保存返回的 C 字符串,最终再将它转换成 Swift 里的字符串返回。
格式化
代码写好了,就剩下格式问题, strftime 和 DateFormatter 的格式不一样,后者通常是直接使用对应的宏,比如 yyyy 代表了四位数字的年份,而 yy 是两位数字的年份,前者则使用的占位符, %Y 等同于 yyyy , %y 则等同于 yy ……
strftime 的完整符号列表见 这里(英文),这里(中文)
使用
接下来就可以使用一行代码实现格式化时间日期输出了:
1 |
print(Date().formattedTime(format: "%y|%Y|%m|%d|%I|%H|%M|%S|%w")) |
😎
参考文献
- https://github.com/aciidb0mb3r/SPM-PkgConfig/blob/master/Sources/POSIX/strftime.swift
- https://www.runoob.com/python/att-time-strftime.html
- https://wiki.jikexueyuan.com/project/c/strftime.html
- https://stackoverflow.com/questions/30932465/how-to-format-string-in-swift-using-strftime
本文由 落格博客 原创撰写:落格博客 » Swift 使用 strftime 快速格式化时间和日期
转载请保留出处和原文链接:https://www.logcg.com/archives/3309.html