计算一天的开始和结束。迅速

时间:2016-03-11 14:43:16

标签: swift date nsdateformatter nscalendar

我有一个函数来计算一周的开始和结束,它按预期工作。我想实现另一个功能,它可以解决一天的开始和结束。我有下面的代码但是我得到以下错误:

  

在没有更多上下文的情况下,表达式的类型不明确。

public class Date {
    let dateFormatter = NSDateFormatter()
    let date = NSDate()
    let calendar = NSCalendar.currentCalendar()

    func calcStartAndEndDateForWeek(durationOccurance: Double) {
        print("Calculating start and end for week")
        let componentsWeek = calendar.components([.YearForWeekOfYear, .WeekOfYear], fromDate: date)
        let startOfWeek = calendar.dateFromComponents(componentsWeek)!

        print("start of Week = \(dateFormatter.stringFromDate(startOfWeek))")

        let componentsWeekEnds = NSDateComponents()
        componentsWeekEnds.weekOfYear = 1
        let endOfWeek = calendar.dateByAddingComponents(componentsWeekEnds, toDate: startOfWeek, options: [])!

        print("End of the week = \(dateFormatter.stringFromDate(endOfWeek))")
    }


    func calcStartAndEndDateForDay(durationOccurance: Double) {
        print("Calculating start and end for day")
        let componentsWeek = calendar.components([.Minutes, .Seconds], fromDate: date)
        let startOfDay = calendar.dateFromComponents(componentsWeek)!
        print("start day = \(dateFormatter.stringFromDate(startOfDay))")
    }

    init(){
        dateFormatter.dateFormat = "dd-MM-yyyy"
        }
   }

2 个答案:

答案 0 :(得分:3)

我们可以使用NSCalendar

上的方法创建更通用的函数
func rangeOfPeriod(period: NSCalendarUnit, date: NSDate) -> (NSDate, NSDate) {
    let calendar = NSCalendar.currentCalendar()    
    var startDate: NSDate? = nil

    // let's ask calendar for the start of the period
    calendar.rangeOfUnit(period, startDate: &startDate, interval: nil, forDate: date)

    // end of this period is the start of the next period
    let endDate = calendar.dateByAddingUnit(period, value: 1, toDate: startDate!, options: [])

    // you can subtract 1 second if you want to make "Feb 1 00:00:00" into "Jan 31 23:59:59"
    // let endDate2 = calendar.dateByAddingUnit(.Second, value: -1, toDate: endDate!, options: [])

    return (startDate!, endDate!)
}

被称为

 print("\(rangeOfPeriod(.WeekOfYear, date: NSDate()))")
 print("\(rangeOfPeriod(.Day, date: NSDate()))")

将它放入您的代码:

public class Date {
    let dateFormatter = NSDateFormatter()
    let date = NSDate()
    let calendar = NSCalendar.currentCalendar()

    func rangeOfPeriod(period: NSCalendarUnit) -> (NSDate, NSDate) {
        var startDate: NSDate? = nil

        calendar.rangeOfUnit(period, startDate: &startDate, interval: nil, forDate: date)

        let endDate = calendar.dateByAddingUnit(period, value: 1, toDate: startDate!, options: [])

        return (startDate!, endDate!)
    }

    func calcStartAndEndDateForWeek() {
        let (startOfWeek, endOfWeek) = rangeOfPeriod(.WeekOfYear)

        print("Start of week = \(dateFormatter.stringFromDate(startOfWeek))")
        print("End of the week = \(dateFormatter.stringFromDate(endOfWeek))")
    }


    func calcStartAndEndDateForDay() {
        let (startOfDay, endOfDay) = rangeOfPeriod(.Day)

        print("Start of day = \(dateFormatter.stringFromDate(startOfDay))")
        print("End of the day = \(dateFormatter.stringFromDate(endOfDay))")
    }

    init() {
        dateFormatter.dateFormat = "dd-MM-yyyy"
    }
}

let myDate = Date()
myDate.calcStartAndEndDateForWeek()
myDate.calcStartAndEndDateForDay()

答案 1 :(得分:0)

我正在实施类似的东西,并采取以下路线:

extension Date {
    static var startOfToday: Date? {
        let date = Date()
        guard !date.isStartOfDay else { return date }
        return date
            .zero(out: .second)?
            .zero(out: .minute)?
            .zero(out: .hour)?
            .addingTimeInterval(-24 * 60 * 60)
    }

    private func zero(out: Calendar.Component) -> Date? {
        return Calendar.current
            .date(bySetting: out, value: 0, of: self)
    }

    private var isStartOfDay: Bool {
        let cal = Calendar.current
        let hours = cal.component(.hour, from: self)
        let minutes = cal.component(.minute, from: self)
        let seconds = cal.component(.second, from: self)
        return hours == 0 && minutes == 0 && seconds == 0
    }
}

将组件设置为零将增加下一个更大的组件。因此,将小时设置为零会将日期推迟到00:00的第二天,除非小时已经为零。因此,为了使其适用于任何日期,我们必须将秒,分钟和小时(按此顺序)清零。为了确保我们不会在昨天开始结束,我们首先检查所有值是否都不是零。

我意识到这有点像hacky,可能不是解决这个问题的最佳方式,但它似乎至少对我的用例来说还算得很好。

只需再添加一天,就可以在此基础上建立一天的结束。