Hi developers im trying to get the date & time from UIDatePicker
my UIDatePicker in on an alert
let myDatePicker: UIDatePicker = UIDatePicker()
let loc = Locale(identifier: "Es_mx")
//myDatePicker.timeZone = NSTimeZone.local
myDatePicker.locale = loc
let date = myDatePicker.date
let components = Calendar.current.dateComponents([.hour, .minute, .year, .day, .month], from: date)
let year = components.year!
let day = components.day!
let month = components.month!
let hour = components.hour!
let minute = components.minute!
myDatePicker.frame = CGRect(x: 0, y: 15, width: 270, height: 200)
let alertController = UIAlertController(title: "\n\n\n\n\n\n\n\n", message: nil, preferredStyle: UIAlertController.Style.alert)
alertController.view.addSubview(myDatePicker)
//let somethingAction = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
let somethingAction = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default) { (somethingAction: UIAlertAction!) in
print("dia: \(day), mes: \(month), año: \(year), hora: \(hour), minuto: \(minute)")
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil)
alertController.addAction(somethingAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion:{})
}
already try
let date = myDatePicker.date
let components = Calendar.current.dateComponents([.hour, .minute, .year, .day, .month], from: date)
let year = components.year!
let day = components.day!
let month = components.month!
let hour = components.hour!
let minute = components.minute!
so when the user press OK button it prints:
print("dia: \(day), mes: \(month), año: \(year), hora: \(hour), minuto: \(minute)")
Print shows current day, month, year, hour and minute
im expect to get what the user selected from UIDatePicker
You initialize a datePicker and get the date from it immediately. This is the problem.
If you want to get the date from the datePicker at the time OK button pressed, you must do this in your closure. Move let date = myDatePicker.date line into your closure, Like so:
let somethingAction = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default) { (somethingAction: UIAlertAction!) in
let date = self.myDatePicker.date
print("dia: \(day), mes: \(month), año: \(year), hora: \(hour), minuto: \(minute)")
}
Related
In my to-do app, I'm trying to set local notification at the time when dead line date for task have been came, but i can't figure out whats wrong with calendar trigger, interval trigger working ok. In function body i put default Date()
func setupNotifications(id: String, contentTitle: String, contentBody: String, date: Date) {
center.getNotificationSettings { (settings) in
if (settings.authorizationStatus == .authorized) {
let content = UNMutableNotificationContent()
content.title = contentTitle
content.body = contentBody
content.sound = .default
let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour], from: Date().addingTimeInterval(5))
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let trigger2 = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger)
let request2 = UNNotificationRequest(identifier: id, content: content, trigger: trigger2)
self.center.add(request)
}
}
You said:
let dateComponents = Calendar.current.dateComponents(
[.year, .month, .day, .hour], from: Date().addingTimeInterval(5)
)
A time interval is reckoned in seconds. But your dateComponents doesn't have any seconds; you've told it to consider only the year, the month, the day, and the hour. And that time is in the past.
You can see this simply by converting your date components back to a date:
let d = Date()
print(d) // 2022-12-01 14:24:02 +0000
let dateComponents = Calendar.current.dateComponents(
[.year, .month, .day, .hour],
from: d.addingTimeInterval(5)
)
let d2 = Calendar.current.date(from: dateComponents)
print(d2) // 2022-12-01 14:00:00 +0000
So at the very least you would need to include .seconds in your list of components. That, as you can see, changes everything:
import UIKit
let d = Date()
print(d) // 2022-12-01 14:25:22 +0000
let dateComponents = Calendar.current.dateComponents(
[.year, .month, .day, .hour, .second],
from: d.addingTimeInterval(5)
)
let d2 = Calendar.current.date(from: dateComponents)
print(d2) // 2022-12-01 14:00:27 +0000
found solution here
https://github.com/YoussifHany51/ToDoList/blob/main/ToDoList/Models/localNotification.swift
adopted to my project
func setupNotifications(id: String, deadline:Date?) {
if deadline != nil {
let calendar = Calendar.current
let hour = calendar.component(.hour, from: deadline ?? Date())
let minute = calendar.component(.minute, from: deadline ?? Date())
let second = calendar.component(.second, from: deadline ?? Date())
let day = calendar.component(.day, from: deadline ?? Date())
let month = calendar.component(.month, from: deadline ?? Date())
let content = UNMutableNotificationContent()
content.title = "To Do"
content.subtitle = "Today is deadline for: \(id)"
content.sound = .default
var operationDate = DateComponents()
operationDate.hour = hour
operationDate.minute = minute
operationDate.second = second
operationDate.month = month
operationDate.day = day
//Trigger
let trigger = UNCalendarNotificationTrigger(dateMatching: operationDate, repeats: false)
//Request
let requst = UNNotificationRequest(
identifier: id, content: content,trigger: trigger
)
UNUserNotificationCenter.current().add(requst)
}
}
I have an alert which has a datepicker in a textfield. I want to reference this textfield to the objc for added properties, how would I be able to do this? I tried to use the following method but it does not work with error 'alert not in scope'.
Alert
#IBAction func info(_ sender: Any) {
let alert9 = UIAlertController (title: "Add Your Info", message: nil, preferredStyle: UIAlertController.Style.alert)
let cancel9 = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil)
alert9.addAction(cancel9)
alert9.addTextField { (textfieldDate: UITextField) in
textfieldDate.placeholder = "Date"
self.datePickerWeight = UIDatePicker()
self.datePickerWeight!.preferredDatePickerStyle = .wheels
self.datePickerWeight?.datePickerMode = .date
self.datePickerWeight?.addTarget(self, action: #selector(ViewController.dateChangedInfo(datePicker:)), for: .valueChanged)
textfieldDate.inputView = self.datePickerInfo
let dateFormatterWeight = DateFormatter()
dateFormatterInfo.dateFormat = "EEEE, MMM d, yyyy"
let todayDateInfo = dateFormatterInfo.string(from: Date.init())
textfieldDate.text = todayDateInfo
}
alert9.addTextField { (textfieldAddInfo: UITextField) in
textfieldAddInfo.placeholder = "Info"
textfieldAddInfo.keyboardType = .decimalPad
}
let ok9 = UIAlertAction(title: "Save", style: UIAlertAction.Style.default) { (action: UIAlertAction) in print("OK")
let textfieldDate = alert9.textFields![0]
let textfieldAddInfo = alert9.textFields![1]
}
dateChangedInfo objC
#objc func dateChangedInfo(datePicker: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
let stringDate = dateFormatter.string(from: datePicker.date)
let textfieldDate = alert9.textFields?[0] // Cannot find 'alert9' in scope
self.textfieldDate.text = stringDate
self.fetchData(for: stringDate)
}
Make alert9 an instance variable.
var alert9: UIAlertController?
#IBAction func info(_ sender: Any) {
alert9 = UIAlertController (title: "Add Your Info", message: nil, preferredStyle: UIAlertController.Style.alert)
...
}
Hi I'm trying to implement date/time notification but the date is 2 hours off.
Code when selecting date
func SelectTime(sender: UIView){
formatter.timeZone = TimeZone.autoupdatingCurrent
let timePicker = ActionSheetDatePicker(title: "Time:", datePickerMode: UIDatePickerMode.time, selectedDate: userDate, doneBlock: {
picker, userDateWithTime, index in
self.formatter.timeZone = TimeZone.autoupdatingCurrent
self.formatter.dateFormat = "yyyy MMMM dd, HH:mm"
self.dateSelected.text = self.formatter.string(for: userDateWithTime)
//print("User date picked \(self.formatter.string(from: userDateWithTime as! Date))")
return
Code for creating the Notification
let uuid = UUID().uuidString
let notification = UNMutableNotificationContent()
notification.title = "Plus - Todo"
//notification.subtitle
notification.body = taskText.text!
let calendar = Calendar.current
let dateComponents = calendar.dateComponents(in: .current, from: userDateWithTime)
//let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: correctDate!)
let notificationTrigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
//let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: uuid, content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
The problem was that userPickedDateWithTime had a type of Any and not Date. I solved this by creating a formattedDate with the type date and the set the formattedDate = userPickedDateWithTime as! Date and then used the formattedDate instead of userPickedDateWithTime when creating the notification
var formattedDate = Date()
func SelectTime(sender: UIView){
formatter.timeZone = TimeZone.autoupdatingCurrent
let timePicker = ActionSheetDatePicker(title: "Time:", datePickerMode: UIDatePickerMode.time, selectedDate: userDate, doneBlock: {
picker, userDateWithTime, index in
self.formatter.timeZone = TimeZone.autoupdatingCurrent
self.formatter.dateFormat = "yyyy MMMM dd, HH:mm"
self.dateSelected.text = self.formatter.string(for: userDateWithTime)
//print("User date picked \(self.formatter.string(from: userDateWithTime as! Date))")
formattedDate = userPickedDateWithtime as! Date // <-- This solved the problem
return
Notification code
let uuid = UUID().uuidString
let notification = UNMutableNotificationContent()
notification.title = "Plus - Todo"
//notification.subtitle
notification.body = taskText.text!
let calendar = Calendar.current
let dateComponents = calendar.dateComponents(in: .current, from: formattedDate)
//let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: correctDate!)
let notificationTrigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
//let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: uuid, content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
HI guys I have a date picker calculation app and Im wondering why the selected dates are not prtinting to my text lable. This is the code I have
#IBAction func calculateDays(sender: UIButton) {
if startDateTextField.text == "" || endDateTextField == "" {
let alert2 = UIAlertController(title: "Oops!", message: "Please Select a Start Date!", preferredStyle: UIAlertControllerStyle.Alert)
alert2.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert2, animated: true, completion: nil)
}
else {
let start = String(startDateTextField.text)
let end = String(endDateTextField.text)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
guard let startDate = dateFormatter.dateFromString(start), endDate = dateFormatter.dateFromString(end) else {
// You don't have dates, show error(print("error"), do no nothing - your choice.
return
}
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
let secondNewString = "\(components.day) days"
resultNumberOfDays.text = secondNewString
}
}
If I force unwrap as a test it works using (obviously this isn't safe)
let startDate:NSDate = dateFormatter.dateFromString(start)!
let endDate:NSDate = dateFormatter.dateFromString(end)!
any ideas on how to get the calculated dates to appear or letting me know what I'm missing here
thanks
I want to disable previous time ie before current time from datePicker,As in date picker we can use minimum Date to do this.how could we do the same with time picker.
Here is the Code.`
timePicker = [[UIDatePicker alloc] init];
[self.view addSubview:timePicker];
float tempHeight = timePicker.frame.size.height;
timePicker.frame = CGRectMake(0,200 ,self.view.frame.size.width , tempHeight);
timePicker.hidden = YES;
timePickerFormatter= [[NSDateFormatter alloc]init ];
[timePickerFormatter setDateFormat:#"HH:mm"];
**timePicker.datePickerMode = UIDatePickerModeCountDownTimer;**
timePicker.minuteInterval=15;
`
Thanks in Advance Please suggest me if any way to perform this.
In the default UIDatePicker minimum date can be set and the date property has both date and time values and you can set it there itself
[datePicker setMinimumDate:[NSDate date]];
Here
[NSDate date]
gives current date
So you want to disable previous time from current time.
timePicker.date = [NSDate date];
this sets the time to current time, but i don't think you can disable the previous time.
By This method you can provide alert to user if he/she selected the past time time. Condition is that you already placed a check on minimum date as current day.
func handleTimePicker(sender: UIDatePicker) {
let timeFormatterHour = NSDateFormatter()
let timeFormatterMinutes = NSDateFormatter()
timeFormatterHour.dateFormat = "hh"
timeFormatterMinutes.dateFormat = "mm"
let InputTimeHourString = timeFormatterHour.stringFromDate(sender.date)
let InputTimeMinutesString = timeFormatterMinutes.stringFromDate(sender.date)
let InputTimeHourInt = Int(InputTimeHourString)!
let InputTimeMinutesInt = Int(InputTimeMinutesString)!
let calculatedInputMinutes = (InputTimeHourInt * 60) + InputTimeMinutesInt
let TodayTime = NSDate()
let TodayTimetimeFormatterHour = NSDateFormatter()
let TodayTimetimeFormatterMinutes = NSDateFormatter()
TodayTimetimeFormatterHour.dateFormat = "hh"
TodayTimetimeFormatterMinutes.dateFormat = "mm"
let TodayTimeInputTimeHourString = TodayTimetimeFormatterHour.stringFromDate(TodayTime)
let TodayTimeInputTimeMinutesString = TodayTimetimeFormatterMinutes.stringFromDate(TodayTime)
let TodayTimeInputTimeHourInt = Int(TodayTimeInputTimeHourString)!
let TodayTimeInputTimeMinutesInt = Int(TodayTimeInputTimeMinutesString)!
let TodayTimecalculatedInputMinutes = (TodayTimeInputTimeHourInt * 60) + TodayTimeInputTimeMinutesInt
if TodayTimecalculatedInputMinutes - calculatedInputMinutes < 0
{
let shownDateFormatter = NSDateFormatter()
shownDateFormatter.dateFormat = "hh:mm a"
self.txtTimeEvent.text = shownDateFormatter.stringFromDate(sender.date)
}
else
{
let alertController = UIAlertController(title: "Time Selection Problem", message:
"You cannot select the Past time", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
let shownTime = NSDate()
let shownTimeFormatter = NSDateFormatter()
shownTimeFormatter.dateFormat = "hh:mm a"
self.txtTimeEvent.text = shownTimeFormatter.stringFromDate(shownTime)
}
}
Swift : Add this line in your Picker Function.its Only allow future Time.
My_Pickername.minimumDate = NSDate()
You posted your question two years ago but this may help anyone who will face this issue, I had the same problem today, and here's the solution:
It doesn't really disable previous dates, but if a user selects a previous date, the above function will display an alert and reset the UIDatePicker to the current date :
Swift 4 :
#IBAction func dateChanged(_ sender: Any) {
let dtp = sender as! UIDatePicker
if Date() <= dtp.date {
print ("correct date")
} else {
dtp.date = Date()
let alert = UIAlertController(title: "Error", message: "You have to choose a correct date", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
}