Swift 3 Easy way to truncate Date to start of the day/month/year

倾然丶 夕夏残阳落幕 提交于 2020-06-25 09:26:05

问题


Is there any easy way to truncate date like we can do in Oracle Database? For example, I need to set value starting from midnight. In Oracle I can do TRUNC(SYSDATE). But I cannot see similar way to do it in Swift. I checked StackOverflow and saw some examples with DateFormatter, Date Components with converting Date to String. I have also seen this question, but didn't understand how to handle Date (not NSDate) type and i

But I don't need String values. And I would like to avoid converting to string and back to Date. I just want to get three values:

Start of the current date (just like we do TRUNC(SYSDATE) in Oracle)

Start of the month (just like we do TRUNC(SYSDATE, 'MONTH') in Oracle)

Start of the year (just like we do TRUNC(SYSDATE, 'YEAR') in Oracle)

I tried this, but it does not return midnight:

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

What should I do?


回答1:


Note the +0000 at the end of the time in your sample.

The start of the day where? I updated the sample to show what you want.

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)

It prints 2017-06-14 00:00:00 +0000. Again, note the +0000 at the end.

By default the timezone is set to be the current timezone and the hour, minute, and second are 0 in that timezone.


I will assume that you want the current timezone. With that stipulation, your code is correct.




回答2:


Calendar has a dedicated methods:

  • Start of the day

    let truncated = Calendar.current.startOfDay(for: Date())
    
  • Start of the month

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

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

Or as Date extension

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)

Regarding the time zone issue you can set the time zone of the current calendar accordingly.



来源:https://stackoverflow.com/questions/44554048/swift-3-easy-way-to-truncate-date-to-start-of-the-day-month-year

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!