Showing dates of specific weekday in UIDatePicker - ios

I have a UIDatePicker and I want to show only the dates of specific weekday in of the picker.
For example, if I select Mon 26 March then I should only see
2 April,
9 April,
16 April,
23 April
and so on in the UIDatePicker. How can this be achieved using UIDatePicker

I Think there is no build-in functionality that can be used to accomplish this , you can create a pickerView and get week dates by adding this to the current
extension Date
{
var nextDateWeak : Date {
return Calendar.current.date(byAdding: .day, value: 6 , to: self )!
}
}

Related

Simulator vs real device return different weekOfYear from Date

I have a Date object from which I need to get a weekOfYear and my code works great on a real device, but it's one weekOfYear ahead on the simulator if I select Sunday. All other days of the week work fine.
I know the simulator uses the mac's date and time, but both the mac and the real device are set to auto, same time zone, same settings.
let wednesday: Date? = calendar.date(from: DateComponents(year: 2020, month: 10, day: 14))
let sunday: Date? = calendar.date(from: DateComponents(year: 2020, month: 10, day: 18))
print("\(wednesday?.weekOfYear) vs \(sunday?.weekOfYear)")
// In the simulator this prints Optional(42) vs Optional(43)
// On a real device this prints Optional(42) vs Optional(42)
Any idea what I'm doing wrong? Does it have anything to do with daylight savings time? The date objects themselves are printed as 2020-10-13 23:00:00 +0000 and 2020-10-17 23:00:00 +0000, but nonetheless, adding 1h for DST should mean it's still Sunday the 18th.
Thanks in advance for any tips.
Update
Thanks for the comments everyone, they helped me find the issue.
The calendar I am using is this:
var calendar: Calendar {
var calendar = Calendar(identifier: .iso8601)
calendar.firstWeekday = 2
return calendar
}
And I have a Date extension to get .weekday which looks like this:
extension Date {
var weekday: Int { return Calendar.current.component(.weekday, from: self) }
}
So the problem was that I was not using my iso8601 calendar, which starts the week on Monday. I changed it to my calendar and it now works.
As I already mentioned in my comment the problem is the calendar ISO8601 you were using. The first weekday of that calendar is Monday while the current calendar (probably Gregorian) the first weekday is Sunday.
Perhaps there is a difference between the simulator and the real device.
Becausue it has a different locale timeZone, please ensure they are same.

How to disable specific days in UIDatePicker

I have a UIDatePicker that should show only specific days, like all Sundays and Mondays, and disable all other dates, The user can select only Sunday and Monday from this week, next week, the week after, to, let's say, 2020.
Is that even possible with UIDatePicker, or even any custom control?
I would suggest you to use like this:
From below code you will get dates of all the Sundays from 2016-2018,
let cal = Calendar.current
// Get the date of 2 years ago today
let stopDate = cal.date(byAdding: .year, value: -2, to: Date())!
// We want to find dates that match on Sundays at midnight local time
var comps = DateComponents()
comps.weekday = 1 // Sunday
// Enumerate all of the dates
cal.enumerateDates(startingAfter: Date(), matching: comps, matchingPolicy: .previousTimePreservingSmallerComponents, repeatedTimePolicy: .first, direction: .backward) { (date, match, stop) in
if let date = date {
if date < stopDate {
stop = true // We've reached the end, exit the loop
} else {
print("\(date)") // do what you need with the date
}
}
}
The logic is simple. Make an array of this is in your required dateFormat and show that in pickerView which will eventually work as datePicker for you.
Hope this helps.
This is impossible. You have to create custom date picker based on UIPickerView.
There is a way to do it with just the UIDatePicker!
Lets say you have a minTime that is January 16 10:00AM
You would do something like this:
let picker = UIDatePicker()
picker.minimumDate = minTime
picker.maximumDate = minTime.changing(.hour, value: 23).changing(.minute, value: 59)
Then the picker will be stuck to that date.
Hope this helps someone!

Swift Month year pickerView with last 12 months

I am having a filter on a tableView, that has a 'From' and 'To' Months selection.
Month selection, I mean, when I select Month, the datePicker should show Month Year only. And the list should contain last 12 months from today.
I looked at the default UIDatePicker but realized that it is not possible to get only Month-Year. (Reference answer from SO)
Further looking, I found this link that has a custom month-year picker but it shows future 15 years. And, upon selection of any row, nothing happens.
Can someone help me customize it to show last 12 months from today and fetch the result upon selection?
This is a simple example to get the last 12 months
var last12Months = [Date]()
let firstDayComponent = DateComponents(day: 1)
Calendar.current.enumerateDates(startingAfter: Date(),
matching: firstDayComponent,
matchingPolicy: .nextTime,
direction: .backward,
using: { (date, idx, stop) in
if let date = date {last12Months.append(date) }
if last12Months.count == 12 { stop = true }
})
print(last12Months)
let formatter = DateFormatter()
formatter.dateFormat = "MMMM yyyy"
print(last12Months.map({formatter.string(from: $0)}))

how to get today's date less 18 years

What is the correct way to get date of 18 years ago from today's Date in Swift3?
In Swift2, I had
let startingDate = NSDate(timeIntervalSinceNow: -600000000)
If you want date with 18 year less you can use Calendar unit year for that.
let date = Calendar.current.date(byAdding: .year, value: -18, to: Date())
Output

List of Days of this week

I need a list of days of the week (with the week starting on Monday) for a timecard list. Im not sure how to achieve this. I have tried some dateByAddingUnit and subtracting from there but it hasn't produced the results I want.
Any idea how to get a list of the dates? (i.e. Monday would be 3/28/16, Tuesday 3/29/16 and so on)
Edit: missed that you want a week to always start on a Monday
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let today = gregorian.startOfDayForDate(NSDate())
let startOfWeek: NSDate
if gregorian.component(.Weekday, fromDate: today) == 2 {
// Today is Monday
startOfWeek = today
} else {
// Find the last Monday prior to today
startOfWeek = gregorian.nextDateAfterDate(today, matchingUnit: .Weekday, value: 2, options: [.SearchBackwards, .MatchPreviousTimePreservingSmallerUnits])!
}

Resources