Creating a date with DateComponents

本秂侑毒 提交于 2021-02-04 21:49:18

问题


I want to get the first day and the last day of the week. But my results do not match the documentation from apple: https://developer.apple.com/documentation/foundation/nsdatecomponents/1410442-weekday

This is my function:

func startAndEndDateOfWeek(weekOfYearWithYear: (week: Int,year: Int)) -> (start: Date, end: Date) {
    var output = (start: Date.init(), end: Date.init())

    let calendar = Calendar(identifier: .gregorian)
    var firstDayComponents = DateComponents()
    firstDayComponents.weekOfYear = weekOfYearWithYear.week
    firstDayComponents.yearForWeekOfYear = weekOfYearWithYear.year
    firstDayComponents.weekday = 1

    let firstDay = calendar.date(from: firstDayComponents)

    var lastDayComponents = DateComponents()
    lastDayComponents.weekOfYear = weekOfYearWithYear.week
    lastDayComponents.yearForWeekOfYear = weekOfYearWithYear.year
    lastDayComponents.weekday = 2

    let lastDay = calendar.date(from: lastDayComponents)
    output = (start: firstDay!, end: lastDay!)
    return output
}

.weekday = 2 -> leads to the sunday and not 0.

I also want to have the entire day and not 16:00.


回答1:


A couple of observations:

  1. In the Gregorian calendar, weekday = 1 means Sunday; weekday = 2 means Monday; etc. You can look at calendar.maximumRange(of: .weekday) to get the range of valid values, and you can look at calendar.weekdaySymbols to see what these weekDay values mean (e.g. “Sun”, “Mon”, “Tue”, “Wed”, “Thu”, “Fri”, and “Sat”).

  2. You said:

    I also want to have the entire day and not 16:00.

    A Date object references a moment in time. So it can’t represent an “entire day”. But it can represent midnight (and midnight in your time zone is likely 4pm in GMT/UTC/Zulu).

    You can, alternatively, return a DateInterval, which does represent a range of time.

    func interval(ofWeek week: Int, in year: Int) -> DateInterval {
        let calendar = Calendar.current
    
        let date = DateComponents(calendar: calendar, weekOfYear: week, yearForWeekOfYear: year).date!
        return calendar.dateInterval(of: .weekOfYear, for: date)!
    }
    

    And then

    let formatter = DateIntervalFormatter()
    formatter.dateStyle = .short
    formatter.timeStyle = .short
    
    let year = Calendar.current.component(.year, from: Date())
    let dateInterval = interval(ofWeek: 2, in: year)
    print(formatter.string(from: dateInterval))
    

    In a US locale, the interval starts on January 6th:

    1/6/19, 12:00 AM – 1/13/19, 12:00 AM

    Whereas in a German locale, the interval starts on the 7th:

    07.01.19, 00:00 – 14.01.19, 00:00

  3. If you want the start of the first day of the week and the last day of the week, you can do:

    func startAndEndDate(ofWeek week: Int, in year: Int) -> (Date, Date) {
        let date = DateComponents(calendar: calendar, weekOfYear: week, yearForWeekOfYear: year).date!
        let lastDate = calendar.date(byAdding: .day, value: 6, to: date)!
    
        return (date, lastDate)
    }
    

    And then

    let formatter = DateFormatter()
    formatter.dateStyle = .short
    
    let year = Calendar.current.component(.year, from: Date())
    let (start, end) = startAndEndDate(ofWeek: 2, in: year)
    print(formatter.string(from: start), "-", formatter.string(from: end))
    


来源:https://stackoverflow.com/questions/54938512/creating-a-date-with-datecomponents

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