How to get Monday's date of the current week in swift

前端 未结 8 1710
死守一世寂寞
死守一世寂寞 2020-11-29 05:36

I\'m trying to get Monday\'s date of the current week. This is treated as the first day of the week in my table view. I also need to get Sunday\'s of the current week. This

相关标签:
8条回答
  • 2020-11-29 05:52

    Swift 4 Solution

    I have figured out according to my requirement, where I have find out dates for following.

    1. Today
    
    2. Tomorrow 
    
    3. This Week 
    
    4. This Weekend 
    
    5. Next Week 
    
    6. Next Weekend
    

    So, I have created Date Extension to get Dates of Current Week and Next Week.

    CODE

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

    USAGE:

    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
    

    You can modify Extension according to your need.

    Thanks!

    0 讨论(0)
  • 2020-11-29 05:54

    Here's a simplified version of Sandeep's answer.

    Usage:

    Date().next(.monday)
    Date().next(.monday, considerToday: true)
    Date().next(.monday, direction: .backward)
    

    Extension:

    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
    }
    
    0 讨论(0)
  • 2020-11-29 05:57

    I wrote Date extensions to get Date for certain weekday and here is how easy it is to use with 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
    

    And here is Date extension for that,

    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 { $0.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
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-11-29 06:00

    You can use calendar ISO8601 where the first weekday is Monday:

    Swift 5.2 or later

    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"
    

    Implemented as a Date computer property extension:

    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"
    
    0 讨论(0)
  • 2020-11-29 06:00

    Try to use:

    calendar.firstWeekday = 2
    

    Edit

    To be more specific: NSCalendar.currentCalendar() returns user calendar. According to docs:

    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.

    If you want always Monday as first day, I think you should use:

    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    calendar!.firstWeekday = 2
    
    0 讨论(0)
  • 2020-11-29 06:02

    Here is the extension I created, first it finds sunday and then it adds one day

    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)
        }
    }
    
    0 讨论(0)
提交回复
热议问题