【问题标题】:Swift 3 Easy way to truncate Date to start of the day/month/yearSwift 3 将日期截断为日/月/年开始的简单方法
【发布时间】:2017-06-14 20:20:24
【问题描述】:

有什么简单的方法可以像在 Oracle 数据库中那样截断日期吗? 例如,我需要从午夜开始设置值。在 Oracle 中,我可以执行 TRUNC(SYSDATE)。但我在 Swift 中看不到类似的方法。 我检查了 StackOverflow 并看到了一些使用 DateFormatter 的示例,将 Date 转换为 String 的 Date Components。我也看过this question,但不明白如何处理日期(不是NSDate)类型和我

但我不需要字符串值。而且我想避免转换为字符串并返回日期。我只想得到三个值:

当前日期的开始(就像我们在 Oracle 中做 TRUNC(SYSDATE))

月初(就像我们在 Oracle 中执行 TRUNC(SYSDATE, 'MONTH') 一样)

年初(就像我们在 Oracle 中执行 TRUNC(SYSDATE, 'YEAR') 一样)

我试过了,但它不返回午夜:

let comp: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
let truncated = Calendar.current.date(from: comp)!

我该怎么办?

【问题讨论】:

  • 我有个坏消息要告诉你:不是每天都有午夜。
  • 嗯...为什么?一些背景:我需要提取当前日期、当前月份、当前年份的统计信息。我将其用作临时解决方案: Date().addingTimeInterval((-1)*60*60*24) 但这不是我想要的。
  • 好的,我已将标题更改为“一天/月/年的开始”。听起来好多了。
  • 由于夏令时等原因:stackoverflow.com/a/17726013/3141234

标签: datetime swift3


【解决方案1】:

Calendar 有专门的方法:

  • 一天的开始

      let truncated = Calendar.current.startOfDay(for: Date())
    
  • 月初

      let now = Date()
      var startOfMonth = now
      var timeInterval : TimeInterval = 0.0
      Calendar.current.dateInterval(of: .month, start: &startOfMonth, interval: &timeInterval, for: now)
    
      print(startOfMonth)
    
  • 年初

      let now = Date()
      var startOfYear = now
      var timeInterval : TimeInterval = 0.0
      Calendar.current.dateInterval(of: .year, start: &startOfYear, interval: &timeInterval, for: now)
    
      print(startOfYear)
    

或作为Date 扩展名

extension Date {
    
    func startOf(_ dateComponent : Calendar.Component) -> Date {
        var calendar = Calendar.current
        calendar.timeZone = TimeZone(secondsFromGMT: 0)!
        var startOfComponent = self
        var timeInterval : TimeInterval = 0.0
        calendar.dateInterval(of: dateComponent, start: &startOfComponent, interval: &timeInterval, for: now)
        return startOfComponent
    }
}

let now = Date()

let startOfDay = now.startOf(.day)
let startOfMonth = now.startOf(.month)
let startOfYear = now.startOf(.year)

关于时区问题,您可以相应地设置当前日历的时区。

【讨论】:

  • 好的,谢谢。我看到了这个方法,但它并没有帮助我开始这个月。无论如何,杰弗里的回答对我来说似乎是有效的。我错过了 TimeZones 问题。
  • 我更新了月份和年份各自方式的答案。
  • 谢谢。您的解决方案看起来也有效。但正如杰弗里所说 - 最初没有问题。我只是错过了 TimeZone 问题 :)
【解决方案2】:

请注意示例中时间末尾的+0000

一天的开始在哪里?我更新了示例以显示您想要的内容。

var comp: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
comp.timeZone = TimeZone(abbreviation: "UTC")!
let truncated = Calendar.current.date(from: comp)!
print(truncated)

它打印2017-06-14 00:00:00 +0000。再次注意末尾的 +0000。

默认情况下,时区设置为当前时区,该时区的时、分、秒均为 0。


我假设您想要当前时区。根据该规定,您的代码是正确的。

【讨论】:

  • 嗨。非常感谢!我知道我错过了时区问题。
猜你喜欢
  • 2019-11-04
  • 2020-06-21
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
相关资源
最近更新 更多