使用 DateComponents 创建日期

人气:300 发布:2022-10-16 标签: calendar swift nsdatecomponents

问题描述

我想得到一周的第一天和最后一天.但我的结果与苹果的文档不匹配:

我也想要一整天而不是 16:00.

解决方案

几点观察:

在公历中,weekday = 1 表示周日;weekday = 2 表示星期一;等你可以查看 calendar.maximumRange(of: .weekday) 来获取有效值的范围,你可以查看 calendar.weekdaySymbols 看看这些 weekDay 值表示(例如Sun"、Mon"、Tue"、Wed"、Thu"、Fri"和Sat").

你说:

我也想要一整天而不是 16:00.

Date 对象引用了某个时刻.所以它不能代表一整天".但它可以代表午夜(您所在时区的午夜可能是 GMT/UTC/Zulu 下午 4 点).

您也可以返回一个 DateInterval,它确实代表一个时间范围.

func interval(ofWeek week: Int, in year: Int) ->日期间隔 {让日历 = Calendar.current让 date = DateComponents(calendar: calendar, weekOfYear: week, yearForWeekOfYear: year).date!返回 calendar.dateInterval(of: .weekOfYear, for: date)!}

然后

让 formatter = DateIntervalFormatter()格式化程序.dateStyle = .short格式化程序.timeStyle = .short让 year = Calendar.current.component(.year, from: Date())让 dateInterval = interval(ofWeek: 2, in: year)打印(formatter.string(来自:dateInterval))

在美国地区,时间间隔从 1 月 6 日开始:

19 年 1 月 6 日上午 12:00 – 19 年 1 月 13 日上午 12:00

而在德国语言环境中,间隔从 7 日开始:

07.01.19, 00:00 – 14.01.19, 00:00

如果你想要一周的第一天和一周的最后一天的开始,你可以这样做:

func startAndEndDate(ofWeek week: Int, in year: Int) ->(日期,日期){让 date = DateComponents(calendar: calendar, weekOfYear: week, yearForWeekOfYear: year).date!让 lastDate = calendar.date(byAdding: .day, value: 6, to: date)!返回(日期,最后日期)}

然后

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

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.

解决方案

A couple of observations:

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").

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

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))

251