2016-03-11 6 views
1

У меня есть функция для работы в начале и конце недели, которая работает так, как ожидалось. Я хочу реализовать еще одну функцию, которая работает в начале и в конце одного дня. У меня есть код ниже, однако я получаю следующее сообщение об ошибке:Разработка начала и конца дня. Swift

Type of expression is ambiguous without more context.

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" 
     } 
    } 

ответ

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() 
+0

О, вау, спасибо, что это работает! Что-то, что я хотел сделать дальше, это сделать дату окончания через 2 недели. Будет ли это достижимо с помощью этой функции? –

+0

@JessMurray От этого зависит. Функция просто дает вам диапазон для даты и заданного периода времени. Вы можете добавить 2 недели к текущему дню и использовать функцию результата. – Sulthan

+0

Хорошо спасибо, я думаю, я понимаю, что вы имеете в виду. Если бы я хотел, чтобы недели/дни увеличивались на 2, а не на 1, мне пришлось бы менять продолжительность от 0 до 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, если, конечно, час уже не равен нулю. Поэтому, чтобы заставить его работать на любую дату, мы должны обнулить секунды, минуты и часы (в этом порядке). И чтобы убедиться, что мы не закончили в начале вчерашнего дня, мы сначала проверяем, не все ли значения уже на нуле.

Я понимаю, что это своего рода хакки и, вероятно, не лучший способ сделать это, но, похоже, он работает достаточно хорошо для моего использования.

Получение конца дня можно построить поверх этого, просто добавив еще один день.

Смежные вопросы