SwiftUI:使用日期

让用户输入日期就像将类型为Date@State属性绑定到SwiftUI控件DatePicker一样容易,但是之后事情会变得更加复杂。

您会发现,处理日期非常困难。真的很难。比您想象的要难,而且我已经从事Date相关工作多年了。

看一下这个简单的例子:

let now = Date()
let tomorrow = Date().addingTimeInterval(86400)
let range = now ... tomorrow

这将创建一个从现在(Date()是当前日期)到明天同一时间(86400 = 24 * 60 * 60 是一天的秒数)的范围。

这似乎很容易,但是整天有86,400秒吗?如果这样做的话,很多人将失业!想想夏令时:有时时钟前进(丢失一个小时),有时倒退(获得一个小时),这意味着那一天我们可能有23或25个小时。然后是闰秒(leap seconds):为了适应地球的自转速度而增加的时间。

如果您认为这很困难,请尝试在Mac的终端上运行此程序:cal。这会打印出当月的简单日历,向您显示星期几。现在尝试运行cal 9 1752,它向您显示1752年9月的日历–由于日历从朱利安(Julian)转换到格里高利安(Gregorian)的日历,您会发现整整12天都没有了。

SwiftUI:使用日期_第1张图片
缺少12天的 1752年9月

现在,这就是我之所以这么说并不是为了吓你的原因——毕竟在我们的程序中日期是不可避免的。相反,我希望您了解对于在代码中日期的使用是重要的,我们应该依赖Apple的框架进行计算和格式化。

在项目中,我们将通过三种方式使用日期:

  1. 选择一个合理的默认“唤醒”时间。
  2. 读取他们想醒来的时间。
  3. 显示格式化后的建议就寝时间。

如果需要,我们可以手动完成所有操作,但是您将进入夏令时,润秒和公历日历领域。

最好让iOS为我们完成所有艰苦的工作:工作量少得多,而且无论用户的区域设置如何,都能保证它是正确的。

让我们逐一解决每个问题,首先选择合理的唤醒时间。

如您所见,Swift为我们提供了使用日期的Date,并封装了年,月,日,时,分,秒,时区等。但是,我们不想考虑其中的大部分,我们想说“给我早上8点的起床时间,无论今天是星期几。”

Swift为此有一种略有不同的类型,称为DateComponents,它使我们可以读取或写入日期的特定部分而不是整个内容。

因此,如果我们想要一个表示今天上午8点的日期,我们可以编写如下代码:

var components = DateComponents()
components.hour = 8
components.minute = 0
let date = Calendar.current.date(from: components)

现在,由于日期验证方面的困难,该date(from :)方法实际上返回了一个可选日期,所以最好使用空合运算符来表示“如果失败,请给我返回当前日期”,如下所示:

let date = Calendar.current.date(from: components) ?? Date()

第二个挑战是我们如何读取他们想要醒来的时间。请记住,DatePicker绑定到一个为我们提供大量信息的日期,因此我们需要找到一种仅提取小时和分钟组成部分的方法。

同样,DateComponents可以助您一臂之力:我们可以要求iOS提供日期中的特定组件,然后将其读出来。一个令人困扰的事情是,由于DateComponents的工作方式,我们请求的值与获得的值之间存在脱节:我们可以要求小时和分钟,但是我们将返回带有所有其属性可选值的DateComponents实例。是的,我们知道小时和分钟会在那儿,因为这些正是我们所要求的,但是我们仍然需要拆开可选件或提供默认值。

因此,我们可能会编写如下代码:

let components = Calendar.current.dateComponents([.hour, .minute], from: someDate)
let hour = components.hour ?? 0
let minute = components.minute ?? 0

最后的挑战是如何格式化日期和时间,而Swift再次为我们提供了一种特定的类型来为我们完成大部分工作。这次称为DateFormatter,它使我们可以通过多种方式将日期转换为字符串。

例如,如果我们只想从日期开始的时间,则可以这样写:

let formatter = DateFormatter()
formatter.timeStyle = .short
let dateString = formatter.string(from: Date())

我们还可以设置.dateStyle以获取日期值,甚至可以使用dateFormat以完全自定义的格式进行传递,但这超出了本项目的范围!

关键是日期有点难,但苹果公司为我们提供了很多帮助程序,以减少日期的难度。如果您学会了使用它们,那么您将编写更少的代码,并且也编写更好的代码!

译自 Working with dates

Previous: BetterRest 项目——使用 DatePicker 选择日期和时间 Hacking with iOS: SwiftUI Edition Next: BetterRest 项目——用Create ML训练模型

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:使用日期)