Swift “我该怎么做?”;“合并”;一个未分区的日期和一个时区?

Swift “我该怎么做?”;“合并”;一个未分区的日期和一个时区?,swift,date,timezone,Swift,Date,Timezone,我的问题与(我认为)非常相似。我只想用斯威夫特 无论如何,我正在尝试编写具有以下签名的函数: func combine(_ date: Date, with timeZone: TimeZone) -> Date? 它所做的是,它基本上接受一个日期并返回一个“分区”日期。如果时区中不存在日期,则返回nil 为避免成为XY问题,以下是一个屏幕截图: 我要求用户提供一个日期和一个时区,我想将这两个合并为一个date 我会尽力解释的。我将以timeIntervalFrom1970的格式表示日

我的问题与(我认为)非常相似。我只想用斯威夫特

无论如何,我正在尝试编写具有以下签名的函数:

func combine(_ date: Date, with timeZone: TimeZone) -> Date?
它所做的是,它基本上接受一个日期并返回一个“分区”日期。如果时区中不存在日期,则返回
nil

为避免成为XY问题,以下是一个屏幕截图:

我要求用户提供一个日期和一个时区,我想将这两个合并为一个
date

我会尽力解释的。我将以
timeIntervalFrom1970
的格式表示日期,以便尽可能清楚

假设我传入0作为日期,GMT-1作为时区,它将返回3600。0是1970-1-100:00:00。1970-1-1 00:00:00:00在GMT-1是1970-1-1 01:00:00在GMT,这是3600

这就是我试图实现的方法:

return date.addingTimeInterval(-timeZone.secondsFromGMT(for: date))
这似乎在大多数情况下有效,但并非所有情况下都有效。然而,如果DST介入,整个事情变得一团糟,我认为它不会返回正确的结果。它也让人觉得“数学化”。我更喜欢没有数学的方法,只使用基础API方法。


那么,我如何实现这个方法呢?

在您的示例中,API为您提供了一个
日期,但您想要解释它
在某些特定的时区,这被称为“2017/08/18 8:08”。假设
eureka forms UI元素使用当前日历的时区
对于显示,您可以将日期转换为
DateComponents
,然后再转换回来 到具有不同时区的
日期

func combine(_ date: Date, with timeZone: TimeZone) -> Date? {
    var cal = Calendar.current
    let comp = cal.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: date)
    cal.timeZone = timeZone
    return cal.date(from: comp)
}
如果日期/时间组合不存在,将返回
nil

在另一个时区中。

没有“分区日期”,日期是一个绝对时间点您可以做的是从日期组件(年、月、日、小时、分钟、秒)、时区和日历创建一个日期。@MartinR我知道是的。这就是为什么我要努力做到这一点。我使用的是eureka表单,第一个表行实际上是一个
DateTimeRow
我只能从中得到一个
Date
。我想根据所选时区将此日期转换为新日期。我目前无法对其进行测试,但通过本地时区和其他时区之间的GMT偏移差进行调整应该可以。或者,您可以转换日期->日期组件->日期,第一次转换使用本地时区,第二次转换使用其他时区。存在一个普遍问题:如果用户选择的日期/时间在其他时区中不存在(因为时钟为DST向前调整),该怎么办?在这种情况下,您希望得到什么样的结果例如,印度的用户(据我所知,印度没有DST)可以选择“2017/03/26 02:30德国”,这是不存在的。@MartinR哦,是的!我忘了考虑这一点。我想我会让它归零。编辑。当我选择“今天8:37:37”并打印我得到的日期时。是“2017-08-18 07:37:37+0000”。设备时区以GMT+1为单位。显然,API将所选日期转换为UTC。这是否如您所说的“使用当前日历的时区显示”?那么我应该如何确定它是否使用当前日历的时区显示?您选择了哪个目标时区?转换前后的
日期是多少?等等,我只是在这里打印日期。我只是想弄清楚Eureka是否使用当前日历的时区进行显示。这与时区无关,对吗?我甚至没有使用时区行的值。@Sweeper:
“today 8:37:37”
是GMT+1时区中的“2017-08-18 07:37:37+0000”。
func combine(_ date: Date, with timeZone: TimeZone) -> Date? {
    var cal = Calendar.current
    let comp = cal.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: date)
    cal.timeZone = timeZone
    return cal.date(from: comp)
}