【问题标题】:How to convert timeIntervalSinceNow in swift to a readable date如何将 timeIntervalSinceNow 快速转换为可读日期
【发布时间】:2015-08-16 13:33:57
【问题描述】:

您好,我正在尝试查找某个日期与当前本地时间之间的时间间隔。

var a = eventDate.timeIntervalSinceNow
println(a)
//1404567.32182503 - output

当我尝试这样做时,我得到了如上所述的输出。如何将其更改为可读日期?

我想计算剩余的天数、小时数、分钟数。我不想要年、月、秒。

必须:我想要事件日期和本地时间之间的时间间隔。不是UTC时间。

这里是完整的代码:

//eventDate is 2015-09-01 19:39 
var date = NSDate();
var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "YYY-MM-dd HH:mm:ss ZZZZ"
    dateFormatter.timeZone = NSTimeZone()
    var localDateString = dateFormatter.stringFromDate(date)
var localDate: NSDate = dateFormatter.dateFromString(localDateString)!

var components = NSCalendar.currentCalendar().components(.CalendarUnitSecond |
        .CalendarUnitMinute | .CalendarUnitHour | .CalendarUnitDay |
        .CalendarUnitMonth | .CalendarUnitYear, fromDate: localDate,
        toDate:  self.eventDate, options: nil)

println("\(components.day) days \(components.hour) hours \(components.minute) minutes")

16 days 5 hours 41 minutes //Origianl output
16 days 0 hours 11 minutes // Expected output

我认为由于 UTC 时间的变化而面临这个问题!

【问题讨论】:

  • 提示:使用 NSCalendar 和 NSDateComponents。 SO和互联网上应该有一些例子。
  • 试过了。但是得到不正确的值,因为如果我给出本地时间,无论如何它都需要 UTC 时间!
  • 显示您的尝试,连同您的输入数据、实际结果和预期结果。
  • @MartinR 请看已编辑的问题
  • dateFormat 字符串不正确。请显示原始日期字符串的示例。至少,我会使用yyyy 而不是YYY

标签: ios swift nstimeinterval nstimezone


【解决方案1】:

一些想法:

  1. 如果您想要时差的字符串表示形式(例如,在 UI 中显示),请使用 NSDateComponentsFormatter。例如,在 Swift 3 中:

    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = [.day, .hour, .minute]
    formatter.unitsStyle = .full
    let string = formatter.string(from: date1, to: date2)
    

    或者,在 Swift 2 中:

    let formatter = NSDateComponentsFormatter()
    formatter.allowedUnits = [.Day, .Hour, .Minute]
    formatter.unitsStyle = .Full
    let string = formatter.stringFromDate(date1, toDate: date2)
    

    用你的例子,这将显示:

    16 天 6 小时 9 分钟

    有关配置格式化程序行为的各种属性的详细信息,请参阅the documentation

  2. 在您的问题中,您向我们展示了您的输出:

    16 天 5 小时 41 分钟 // 原始输出
    16 天 0 小时 11 分钟 // 预期输出

    您似乎从该输出推断出比较两个日期时存在一些问题。您比较这两个日期的技术很好(尽管NSDateComponentsFormatter 简化了该过程,并且还生成了本地化字符串)。但是计算两个日期之间经过的时间的例程不是问题。

    问题是您的日期之一(很可能是您使用格式化程序转换的日期)是错误的。

  3. 在 cmets 中,您不断对同一个问题提出不同的排列方式,“我如何比较本地时区的日期?”,答案是“您不知道”。日期没有时区。日期字符串可以,但 NSDate 对象不可以。

    如果您执行printDate/NSDate 对象,它通常会在格林威治标准时间显示它们(您通常会在日期后看到+0000,证实了这一事实)。如果您想在当地时区查看它们,请使用 DateFormatter 并使用 string(from:)(或在 Swift 2 中,NSDateFormatter 并使用 stringFromDate())。

    但是使用这种stringFromDate 机制(其他纯粹用于诊断目的)在您当地的时区查看这些日期没有什么意义。没有“我本地时区中两个 NSDate 对象之间的差异”之类的东西。 NSDate 对象表示世界各地的一个时间点,而 NSTimeZone 仅在您希望将该时间点显示为本地时区的字符串表示时才需要。

归根结底,问题不在于计算两个NSDate 对象之间的经过时间,而在于您如何创建这些NSDate 对象本身。很有可能,来自 parse 的原始字符串(由于某种原因您似乎不愿意与我们分享)不在您认为的时区中。

人们最常犯的错误是假设字符串是在他们的本地时区,而它总是在 GMT/UTC/Zulu 中,除非日期字符串另有明确说明(例如 +0530)。 (在没有时区限定符的情况下使用本地时区的 Web 服务报告日期是一种糟糕的设计,所以希望您不要这样做。)

【讨论】:

  • 但这也没有考虑 DST 转换(因为信息在timeIntervalSinceNow 中丢失了)。最好先计算日期之间的 NSDateComponents。
  • 是的,它显示正确,但相对于我的当地时间,它应该显示:16 天 5 小时 39 分钟!因为我的时间是 GMT+05:30
  • @MartinR 我不同意。如果您正在查找eventDate 和现在之间经过的时间,timeIntervalSinceNow 确实反映了夏令时。如果结果错误,则问题在于原始日期字符串或用于将其转换为NSDate 的格式化程序。不幸的是,没有看到原始字符串的详细示例,很难进一步诊断。
  • 如果我使用 stringFromDate(localDate) 我得到正确的本地日期和时间作为字符串。我怎样才能再次更改此日期?如果我使用 dateFromString,它会再次被更改为 GMT 时间!!!
  • @Rob:我更正了我的评论。似乎 NSDateComponentsFormatter 假定 当前日期 作为起点,因此它在 this 情况下可以正常工作。通常,如果您想显示两个任意日期之间的天/小时/分钟,最好将差异计算为 NSDateComponents 而不是 NSTimeInterval。
猜你喜欢
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多