如何在 swift 中获取本周星期一的日期
How to get Monday's date of the current week in swift
我正在尝试获取本周星期一的日期。在我的 table 视图中,这被视为一周的第一天。
我还需要获取本周的星期日。在我的 table 视图中,这被视为一周的最后一天。
当前尝试:
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
calendar.firstWeekday = 1
//attempt to changefirstday
let dateFormatter = NSDateFormatter()
let theDateFormat = NSDateFormatterStyle.ShortStyle
let theTimeFormat = NSDateFormatterStyle.ShortStyle
dateFormatter.dateStyle = theDateFormat
dateFormatter.timeStyle = theTimeFormat
let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear ], fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
print("startOfWeek is \(startOfWeek)")
let stringDate = dateFormatter.stringFromDate(startOfWeek!)
print("string date is \(stringDate)") //This is returning Sunday's date
尝试使用:
calendar.firstWeekday = 2
编辑
更具体地说:NSCalendar.currentCalendar()
returns 用户日历。根据文档:
The returned calendar is formed from the settings for the current user’s chosen system locale overlaid with any custom settings the user has specified in System Preferences.
如果您希望始终将星期一作为第一天,我认为您应该使用:
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar!.firstWeekday = 2
我写了日期扩展来获取某个工作日的日期,下面是使用 Swift 5,
是多么容易
Date.today() // Oct 15, 2019 at 9:21 AM
Date.today().next(.monday) // Oct 21, 2019 at 9:21 AM
Date.today().next(.sunday) // Oct 20, 2019 at 9:21 AM
Date.today().previous(.sunday) // Oct 13, 2019 at 9:21 AM
Date.today().previous(.monday) // Oct 14, 2019 at 9:21 AM
Date.today().previous(.thursday) // Oct 10, 2019 at 9:21 AM
Date.today().next(.thursday) // Oct 17, 2019 at 9:21 AM
Date.today().previous(.thursday,
considerToday: true) // Oct 10, 2019 at 9:21 AM
Date.today().next(.monday)
.next(.sunday)
.next(.thursday) // Oct 31, 2019 at 9:21 AM
这里是日期扩展,
extension Date {
static func today() -> Date {
return Date()
}
func next(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.next,
weekday,
considerToday: considerToday)
}
func previous(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.previous,
weekday,
considerToday: considerToday)
}
func get(_ direction: SearchDirection,
_ weekDay: Weekday,
considerToday consider: Bool = false) -> Date {
let dayName = weekDay.rawValue
let weekdaysName = getWeekDaysInEnglish().map { [=11=].lowercased() }
assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")
let searchWeekdayIndex = weekdaysName.firstIndex(of: dayName)! + 1
let calendar = Calendar(identifier: .gregorian)
if consider && calendar.component(.weekday, from: self) == searchWeekdayIndex {
return self
}
var nextDateComponent = calendar.dateComponents([.hour, .minute, .second], from: self)
nextDateComponent.weekday = searchWeekdayIndex
let date = calendar.nextDate(after: self,
matching: nextDateComponent,
matchingPolicy: .nextTime,
direction: direction.calendarSearchDirection)
return date!
}
}
// MARK: Helper methods
extension Date {
func getWeekDaysInEnglish() -> [String] {
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: "en_US_POSIX")
return calendar.weekdaySymbols
}
enum Weekday: String {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
enum SearchDirection {
case next
case previous
var calendarSearchDirection: Calendar.SearchDirection {
switch self {
case .next:
return .forward
case .previous:
return .backward
}
}
}
}
您可以使用日历 ISO8601,其中第一个工作日是星期一:
Swift 5.2 或更高版本
extension Calendar {
static let iso8601 = Calendar(identifier: .iso8601)
static let iso8601UTC: Calendar = {
var calendar = Calendar(identifier: .iso8601)
calendar.timeZone = TimeZone(identifier: "UTC")!
return calendar
}()
}
let monday =
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 9, 2020 at 12:00 AM"
print(monday.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayUTC =
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 8, 2020 at 9:00 PM" TimeZone -03:00
print(mondayUTC) // "2020-11-09 00:00:00 +0000\n"
作为 Date 计算机实施 属性 扩展名:
extension Date {
var mondayOfTheSameWeek: Date {
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
var mondayOfTheSameWeekAtUTC: Date {
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
}
let mondayOfTheSameWeek = Date().mondayOfTheSameWeek // "Nov 9, 2020 at 12:00 AM"
print(mondayOfTheSameWeek.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayOfTheSameWeekAtUTC = Date().mondayOfTheSameWeekAtUTC // "Nov 8, 2020 at 9:00 PM"
print(mondayOfTheSameWeekAtUTC) // "2020-11-09 00:00:00 +0000\n"
@Saneep 回答的补充
如果您想根据 given/current 日期获得准确的日期时间(假设您想将星期一的日期时间 -> 23-05-2016 12:00:00
转换为 23-05-2016 05:35:17
),那么试试这个:
func convertDate(date: NSDate, toGivendate: NSDate) -> NSDate {
let calendar = NSCalendar.currentCalendar()
let comp = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: toGivendate)
let hour = comp.hour
let minute = comp.minute
let second = comp.second
let dateComp = calendar.components([.Year, .Month, .Day], fromDate: date)
let year = dateComp.year
let month = dateComp.month
let day = dateComp.day
let components = NSDateComponents()
components.year = year
components.month = month
components.day = day
components.hour = hour
components.minute = minute
components.second = second
let newConvertedDate = calendar.dateFromComponents(components)
return newConvertedDate!
}
这是我创建的扩展程序,首先找到星期日然后添加一天
extension Date {
var startOfWeek: Date? {
let gregorian = Calendar(identifier: .gregorian)
guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
return gregorian.date(byAdding: .day, value: 1, to: sunday)
}
}
这是 的简化版本。
用法:
Date().next(.monday)
Date().next(.monday, considerToday: true)
Date().next(.monday, direction: .backward)
分机:
public func next(_ weekday: Weekday,
direction: Calendar.SearchDirection = .forward,
considerToday: Bool = false) -> Date
{
let calendar = Calendar(identifier: .gregorian)
let components = DateComponents(weekday: weekday.rawValue)
if considerToday &&
calendar.component(.weekday, from: self) == weekday.rawValue
{
return self
}
return calendar.nextDate(after: self,
matching: components,
matchingPolicy: .nextTime,
direction: direction)!
}
public enum Weekday: Int {
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
}
Swift 4 解
我已经根据我的要求弄清楚了,在那里我找到了关注的日期。
1. Today
2. Tomorrow
3. This Week
4. This Weekend
5. Next Week
6. Next Weekend
所以,我创建了 Date Extension
来获取 本周 和 下周 的日期。
代码
extension Date {
func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
var tuple: (thisWeek:[Date],nextWeek:[Date])
var arrThisWeek: [Date] = []
for i in 0..<7 {
arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
}
var arrNextWeek: [Date] = []
for i in 1...7 {
arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
}
tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
return tuple
}
var tomorrow: Date {
return Calendar.current.date(byAdding: .day, value: 1, to: noon)!
}
var noon: Date {
return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}
var startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
func toDate(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
用法:
let arrWeekDates = Date().getWeekDates() // Get dates of Current and Next week.
let dateFormat = "MMM dd" // Date format
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSat = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 2].toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)
let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSat = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 2].toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)
print("Today: \(Date().toDate(format: dateFormat))") // Sep 26
print("Tomorrow: \(Date().tomorrow.toDate(format: dateFormat))") // Sep 27
print("This Week: \(thisMon) - \(thisSun)") // Sep 24 - Sep 30
print("This Weekend: \(thisSat) - \(thisSun)") // Sep 29 - Sep 30
print("Next Week: \(nextMon) - \(nextSun)") // Oct 01 - Oct 07
print("Next Weekend: \(nextSat) - \(nextSun)") // Oct 06 - Oct 07
您可以根据需要修改Extension
。
谢谢!
简单代码(记住要更好地照顾可选项):
let now = Date()
var calendar = Calendar(identifier: .gregorian)
let timeZone = TimeZone(identifier: "UTC")!
let desiredWeekDay = 2
let weekDay = calendar.component(.weekday, from: now)
var weekDayDate = calendar.date(bySetting: .weekday, value: desiredWeekDay, of: now)!
/// Swift will give back the closest day matching the value above so we need to manipulate it to be always included at cuurent week.
if weekDayDate > now, weekDay > desiredWeekDay {
weekDayDate = weekDayDate - 7*24*60*60
}
print(weekDayDate)
我正在尝试获取本周星期一的日期。在我的 table 视图中,这被视为一周的第一天。 我还需要获取本周的星期日。在我的 table 视图中,这被视为一周的最后一天。
当前尝试:
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
calendar.firstWeekday = 1
//attempt to changefirstday
let dateFormatter = NSDateFormatter()
let theDateFormat = NSDateFormatterStyle.ShortStyle
let theTimeFormat = NSDateFormatterStyle.ShortStyle
dateFormatter.dateStyle = theDateFormat
dateFormatter.timeStyle = theTimeFormat
let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear ], fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
print("startOfWeek is \(startOfWeek)")
let stringDate = dateFormatter.stringFromDate(startOfWeek!)
print("string date is \(stringDate)") //This is returning Sunday's date
尝试使用:
calendar.firstWeekday = 2
编辑
更具体地说:NSCalendar.currentCalendar()
returns 用户日历。根据文档:
The returned calendar is formed from the settings for the current user’s chosen system locale overlaid with any custom settings the user has specified in System Preferences.
如果您希望始终将星期一作为第一天,我认为您应该使用:
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar!.firstWeekday = 2
我写了日期扩展来获取某个工作日的日期,下面是使用 Swift 5,
是多么容易Date.today() // Oct 15, 2019 at 9:21 AM
Date.today().next(.monday) // Oct 21, 2019 at 9:21 AM
Date.today().next(.sunday) // Oct 20, 2019 at 9:21 AM
Date.today().previous(.sunday) // Oct 13, 2019 at 9:21 AM
Date.today().previous(.monday) // Oct 14, 2019 at 9:21 AM
Date.today().previous(.thursday) // Oct 10, 2019 at 9:21 AM
Date.today().next(.thursday) // Oct 17, 2019 at 9:21 AM
Date.today().previous(.thursday,
considerToday: true) // Oct 10, 2019 at 9:21 AM
Date.today().next(.monday)
.next(.sunday)
.next(.thursday) // Oct 31, 2019 at 9:21 AM
这里是日期扩展,
extension Date {
static func today() -> Date {
return Date()
}
func next(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.next,
weekday,
considerToday: considerToday)
}
func previous(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.previous,
weekday,
considerToday: considerToday)
}
func get(_ direction: SearchDirection,
_ weekDay: Weekday,
considerToday consider: Bool = false) -> Date {
let dayName = weekDay.rawValue
let weekdaysName = getWeekDaysInEnglish().map { [=11=].lowercased() }
assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")
let searchWeekdayIndex = weekdaysName.firstIndex(of: dayName)! + 1
let calendar = Calendar(identifier: .gregorian)
if consider && calendar.component(.weekday, from: self) == searchWeekdayIndex {
return self
}
var nextDateComponent = calendar.dateComponents([.hour, .minute, .second], from: self)
nextDateComponent.weekday = searchWeekdayIndex
let date = calendar.nextDate(after: self,
matching: nextDateComponent,
matchingPolicy: .nextTime,
direction: direction.calendarSearchDirection)
return date!
}
}
// MARK: Helper methods
extension Date {
func getWeekDaysInEnglish() -> [String] {
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: "en_US_POSIX")
return calendar.weekdaySymbols
}
enum Weekday: String {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
enum SearchDirection {
case next
case previous
var calendarSearchDirection: Calendar.SearchDirection {
switch self {
case .next:
return .forward
case .previous:
return .backward
}
}
}
}
您可以使用日历 ISO8601,其中第一个工作日是星期一:
Swift 5.2 或更高版本
extension Calendar {
static let iso8601 = Calendar(identifier: .iso8601)
static let iso8601UTC: Calendar = {
var calendar = Calendar(identifier: .iso8601)
calendar.timeZone = TimeZone(identifier: "UTC")!
return calendar
}()
}
let monday =
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 9, 2020 at 12:00 AM"
print(monday.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayUTC =
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 8, 2020 at 9:00 PM" TimeZone -03:00
print(mondayUTC) // "2020-11-09 00:00:00 +0000\n"
作为 Date 计算机实施 属性 扩展名:
extension Date {
var mondayOfTheSameWeek: Date {
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
var mondayOfTheSameWeekAtUTC: Date {
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
}
let mondayOfTheSameWeek = Date().mondayOfTheSameWeek // "Nov 9, 2020 at 12:00 AM"
print(mondayOfTheSameWeek.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayOfTheSameWeekAtUTC = Date().mondayOfTheSameWeekAtUTC // "Nov 8, 2020 at 9:00 PM"
print(mondayOfTheSameWeekAtUTC) // "2020-11-09 00:00:00 +0000\n"
@Saneep 回答的补充
如果您想根据 given/current 日期获得准确的日期时间(假设您想将星期一的日期时间 -> 23-05-2016 12:00:00
转换为 23-05-2016 05:35:17
),那么试试这个:
func convertDate(date: NSDate, toGivendate: NSDate) -> NSDate {
let calendar = NSCalendar.currentCalendar()
let comp = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: toGivendate)
let hour = comp.hour
let minute = comp.minute
let second = comp.second
let dateComp = calendar.components([.Year, .Month, .Day], fromDate: date)
let year = dateComp.year
let month = dateComp.month
let day = dateComp.day
let components = NSDateComponents()
components.year = year
components.month = month
components.day = day
components.hour = hour
components.minute = minute
components.second = second
let newConvertedDate = calendar.dateFromComponents(components)
return newConvertedDate!
}
这是我创建的扩展程序,首先找到星期日然后添加一天
extension Date {
var startOfWeek: Date? {
let gregorian = Calendar(identifier: .gregorian)
guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
return gregorian.date(byAdding: .day, value: 1, to: sunday)
}
}
这是
用法:
Date().next(.monday)
Date().next(.monday, considerToday: true)
Date().next(.monday, direction: .backward)
分机:
public func next(_ weekday: Weekday,
direction: Calendar.SearchDirection = .forward,
considerToday: Bool = false) -> Date
{
let calendar = Calendar(identifier: .gregorian)
let components = DateComponents(weekday: weekday.rawValue)
if considerToday &&
calendar.component(.weekday, from: self) == weekday.rawValue
{
return self
}
return calendar.nextDate(after: self,
matching: components,
matchingPolicy: .nextTime,
direction: direction)!
}
public enum Weekday: Int {
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
}
Swift 4 解
我已经根据我的要求弄清楚了,在那里我找到了关注的日期。
1. Today
2. Tomorrow
3. This Week
4. This Weekend
5. Next Week
6. Next Weekend
所以,我创建了 Date Extension
来获取 本周 和 下周 的日期。
代码
extension Date {
func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
var tuple: (thisWeek:[Date],nextWeek:[Date])
var arrThisWeek: [Date] = []
for i in 0..<7 {
arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
}
var arrNextWeek: [Date] = []
for i in 1...7 {
arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
}
tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
return tuple
}
var tomorrow: Date {
return Calendar.current.date(byAdding: .day, value: 1, to: noon)!
}
var noon: Date {
return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}
var startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
func toDate(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
用法:
let arrWeekDates = Date().getWeekDates() // Get dates of Current and Next week.
let dateFormat = "MMM dd" // Date format
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSat = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 2].toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)
let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSat = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 2].toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)
print("Today: \(Date().toDate(format: dateFormat))") // Sep 26
print("Tomorrow: \(Date().tomorrow.toDate(format: dateFormat))") // Sep 27
print("This Week: \(thisMon) - \(thisSun)") // Sep 24 - Sep 30
print("This Weekend: \(thisSat) - \(thisSun)") // Sep 29 - Sep 30
print("Next Week: \(nextMon) - \(nextSun)") // Oct 01 - Oct 07
print("Next Weekend: \(nextSat) - \(nextSun)") // Oct 06 - Oct 07
您可以根据需要修改Extension
。
谢谢!
简单代码(记住要更好地照顾可选项):
let now = Date()
var calendar = Calendar(identifier: .gregorian)
let timeZone = TimeZone(identifier: "UTC")!
let desiredWeekDay = 2
let weekDay = calendar.component(.weekday, from: now)
var weekDayDate = calendar.date(bySetting: .weekday, value: desiredWeekDay, of: now)!
/// Swift will give back the closest day matching the value above so we need to manipulate it to be always included at cuurent week.
if weekDayDate > now, weekDay > desiredWeekDay {
weekDayDate = weekDayDate - 7*24*60*60
}
print(weekDayDate)