Set minimum and maximum date AND TIME in UIDatePicker in Swift - ios

I have to set min and max dates AND time in date picker which I achieved with following properties:
datePicker.datePickerMode = UIDatePickerMode.dateAndTime
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = self.dateFormat
let minDate = dateFormatter.date(from: self.fromDate) //Day before yesterday
let maxDate = dateFormatter.date(from: self.toDate) //Yesterday
datePicker.minimumDate = minDate
datePicker.maximumDate = maxDate
However, I am also showing Time Picker with this, but it is limiting to only 00:00 value after changing time or date.
How do I set min time as 00:00 for 24-hrs time and 12:00 am for 12-hrs time? (Same for max time as 23:59 and 11:59 pm)

Related

Adjusting Swift Date from one timezone to another is not producing expected result

I'm really struggling with dates and timezones.
My understanding is Date is independent of timezone and is just a point in time.
I'm writing a unit test and I want to create a Date object that would represent the time now if the user was in a different timezone than the default London zone I'm running the test from and then convert it to a different timezone.
I start off by creating a Date object using DateComponents with the projected time, in this example, I want Australia/Sydney time which is 11hrs ahead of GMT (my location).
Next, I want to derive a new Date that is adjusted back to GMT i.e. essentially subtracting 11hrs.
The derived date I want is 2022-12-07 13:30:00 +0000. I'm using dateComponents(in:from:) method on Calendar to specify the timezone, according to Apple's documentation:
Returns all the date components of a date, as if in a given time zone (instead of the Calendar time zone).
I then set the timeZone component which should then adjust the time from Australia/Sydney to Europe/London but while it's adjusting the time it's not correctly adjusting the date component which should be shifted one day back.
Here is my code example:
let components = DateComponents(
year: 2022,
month: 12,
day: 8,
hour: 02,
minute: 30,
second: 0
)
let originalDate = Calendar.current.date(from: components)!
// originalDate printed is 2022-12-08 02:30:00 +0000
var components = Calendar.current.dateComponents(in: TimeZone(identifier: "Australia/Sydney")!, from: originalDate)
components.timeZone = TimeZone(identifier: "Europe/London")!
let localTime = components.date!
// localTime printed is 2022-12-08 13:30:00 +0000 but I expected 2022-12-07 13:30:00 +0000 as Sydney is +11hrs ahead of GMT+0.
If your goal is to create a Date that is on 2022-12-08 at 02:30 local time in Sydney then the simplest way is:
let components = DateComponents(
timeZone: TimeZone(identifier: "Australia/Sydney")!,
year: 2022,
month: 12,
day: 8,
hour: 02,
minute: 30,
second: 0
)
let originalDate = Calendar.current.date(from: components)!
That's it. No other conversion is needed. originalDate will show as 2022-12-07 15:30:00 +0000.
The reason you get the result you do is that DateComponents are just a set of components. You can create them from a Date and create a Date from them but they aren't a Date.
You are creating DateComponents from a Date using the Australia/Sydney so you get "13:30" in the hour and minute components and "Australia/Sydney" in the time zone component.
Then you change the timezone component to "Europe/London". This doesn't change any other component, so you now have a set of components that represent 13:30 in London.
Another way of thinking about it, is if you set the hours component to 2 instead of changing the Timezone; You are just going to get 02:30 in Australia/Sydney. It isn't going to change the time zone to UTC
If you want to create a Date at a specific time in a particular Timezone, specify that Timezone in your original date components.
let components = DateComponents(
year: 2022,
month: 12,
day: 8,
hour: 02,
minute: 30,
second: 0
)
let originalDate = Calendar.current.date(from: components)!
// originalDate printed is 2022-12-08 02:30:00 +0000
var components1 = Calendar.current.dateComponents(in: TimeZone(identifier: "Australia/Sydney")!, from: originalDate)
let afterTimeZoneSetDate = Calendar.current.date(from: components1)!
// this prints - "Dec 8, 2022 at 2:30 AM"
components1.timeZone = TimeZone(identifier: "Europe/London")!
let localTime = components1.date
// localTime printed is 2022-12-08 13:30:00 and this is correct.
If you look at the code above, because your original components does not include a timeZone, it does not alter the time after you set "Australia/Sydney", rather it assign a timeZone now. Beyond this since you are changing a timeZone, it will adapt the time accordingly.

how to set date and time limitation in Date Time Picker from Now to 1 Month from Now?

I now that there is a thread that discussing about minimum and maximum date time in here Minimum and maximum date in UIDatePicker
but I am a beginner now in programming, and I have little bit confused with date and time object. I have tried but I can't set up my date time picker properly. So I want to set my date time picker to have minimum and maximum limited time.
the minimum is Now, and the maximum is 1 month from now. what code do I have to use? Thanks in advance
https://i.stack.imgur.com/RxXUX.png
You can try
self.datePicker.minimumDate = Date()
self.datePicker.maximumDate = Calendar.current.date(byAdding: .day, value: 30 , to:Date())!
or
self.datePicker.maximumDate = Calendar.current.date(byAdding: .month, value: 1 , to:Date())!
I recommend to use the date math skills of Calendar. It calculates the same day in the next month. If the day does not exist (for example Feb 30) it returns the next closest available date.
let now = Date()
let calendar = Calendar.current
let dayComponents = calendar.dateComponents([.day], from: now)
let maximumDate = calendar.nextDate(after: now, matching: dayComponents, matchingPolicy: .nextTime)
To get a Date exactly one month in the future from now (taking into account different month lengths), you can use Date.date(byAdding:value:to:), e.g. as in this answer. You'd take the result and set it as maximumDate of your picker.

UIDatePicker minimal value? [duplicate]

This question already has answers here:
How do you create a Swift Date object?
(11 answers)
Closed 5 years ago.
In Swift, I have a var datePicker = UIDatePicker(). I'm trying to set the datePicker to have a minimum value of Jan, 1st, 1920 (I want a range from Jan, 1st, 1920 to current date. I read how to set the maximumDate of the UIDatePicker, that was easy, but I couldn't find how to set the minimum to a specific date. I read that it should be datePicker.minimumDate but I'm not sure how to set the exact date from above. Suggestions?
Create appropriate date components
let components = DateComponents(year: 1920, month: 1, day: 1)
Create a date from the components
let minimumDate = Calendar.current.date(from: components)
Set the minimum date
let picker = UIDatePicker()
picker.minimumDate = minimumDate
You can use the NSDateFormatter as the following:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "YYYY-MM-DD"
let date = dateFormatter.dateFromString("1920-01-01")
let datePicker = UIDatePicker()
datePicker.minimumDate = date

How could I set UIDatePicker to show a day later from current date in swift?

I am trying to make an somewhat alarm app which has mandatory settings at first but the user can configure it by using the UIDatePicker.
The alarm app first has a defalut setting such as a week later from the current time, but it can be changed as the user scrolls the UIDatePicker. I searched a lot but cannot find a suitable answer.
can somebody please help me!
You can set the UIDatePicker date to your desired date time.
let numberOfDays = 6
datePicker.date = NSDate(timeIntervalSinceNow: (((24 * 60) * 60) * numberOfDays))
Hope it will help you..
Swift 4.1:
datePicker.date = Date(timeIntervalSinceNow: (((24 * 60) * 60) * numberOfDays))
Add this line of code when you create date picker.
datePicker.maximumDate = Calendar.current.date(byAdding: .day, value: 0, to: Date())
You can set value increase or decrease and complete your requirement.
let dateString = "Thursday, 19 Jan 2017"
let df = DateFormatter()
df.dateFormat = "eeee, dd MM yyyy"
let date = df.date(from: dateString)
if let unwrappedDate = date {
myDatePicker.setDate(unwrappedDate, animated: false) //set your own date
}

UIDatePicker Time Issues

I have a problem with my UIDatePicker:
When it first appears on the view as you'll see in the screenshot,
the initial value of the UIDatePicker says Today 3:00 pm, but if I click on the done button the label shows 3:07 ( which is the actual time ).
I want the Label to display the same time as the UIDatePicker.
here is my code:
override func viewDidLoad() {
super.viewDidLoad()
myDatePicker.minuteInterval = 15
}
#IBAction func datePickerAction(sender: AnyObject) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
var strDate = dateFormatter.stringFromDate(myDatePicker.date)
self.selectedDate.text = strDate
}
You need to adjust the initial date to the discrete minute amounts at first. I am sure your date picker works just fine once you change the value, right? When you set the date picker to a date (like 3:07) but the date picker is set to show only increments of 15 minutes, it will show 3:00, but the set date is still 3:07.
let allUnits = NSCalendarUnit(rawValue: UInt.max)
let components = NSCalendar.currentCalendar().components(allUnits, fromDate: NSDate())
var minute = components.minute
minute = (minute / 15) * 15
components.minute = minute
let datePickerDate = NSCalendar.currentCalendar().dateFromComponents(components)
This always rounds the minutes downwards (while you might want to round up if the minute % 15 > 7 and then account for rounding up to 60), but you get the idea.

Resources