M/d with Current Year format for DateFormatter - swift

i have a textfield bound to a date with dateformater the dateformat property is set to "M/d". when i enter a string like 3/1 into the textfield it returns 3/1/2000. how can i set it to default to the current year but with out having to type the year in the string.

You can set your date formatter's defaultDate using the start of the current year:
Create your custom date formatter
extension Formatter {
static let monthDay: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "M/d"
return dateFormatter
}()
}
Then add a target for your textField for control event editing changed:
textField.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
Create a method to check every time the textField value changes if the text typed by the user can be parsed by your date formatter. Set the start of the current year as the defaultDate of your dateFormatter:
#objc func editingChanged(_ textField: UITextField) {
let year = Calendar.current.component(.year, from: Date())
let defaultDate = DateComponents(calendar: .current, year: year).date!
Formatter.monthDay.defaultDate = defaultDate
if let date = Formatter.monthDay.date(from: textField.text!) {
print(date.description(with: .current))
}
}

Related

is there a way to set an array of dates all to the same Hour?

I have an array of dates created from a date picker. When they are saved it also adds the hours and minutes. When I compare the dates to be equal some of them are an hour off because of daylight savings time.
Is there a way, after the date picker, to set each date to the same hour or do I have to go through the process of checking for daylight savings time and adding or subtraction an hour? Or should I run the array through a function to make them all equal?
func createDatePicker() {
// format Display of date
datePicker.datePickerMode = .date
// assign datepicker to textfield
dateTextField.inputView = datePicker
// create toolbar
let toolBar = UIToolbar()
toolBar.sizeToFit()
// add item Button
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector (doneClicked))
toolBar.setItems([doneButton], animated: true)
dateTextField.inputAccessoryView = toolBar
}
#objc func doneClicked() {
//format the date display in text field
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.dateFormat = "MM-dd-yyyy"
dateTextField.text = dateFormatter.string(from: datePicker.date)
self.view.endEditing(true)
found a fix.
if let date = dateTextField.text {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
newDate = dateFormatter.date(from: date)!
let tz = TimeZone.current
if tz.isDaylightSavingTime(for: newDate) {
print("date Changed")
newDate += 3600

string to date in my timeZone make wrong date

I'm trying to convert String to date in my country time zone but the result is not as formatted I did
let dbl = TimeInterval(longDate)
let date = Date(timeIntervalSince1970: dbl / 1000)
let formatter = DateFormatter()
print(longDate)
formatter.calendar = Calendar(identifier: .persian)
formatter.locale = Locale(identifier: "fa_IR")
formatter.timeZone = TimeZone(identifier: "IRST")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let a = formatter.string(from: date)
resultDate = dateFormatter.date(from: a)
print(reslutDate,a) //2018-08-02 11:56:28 +0000 incorrect time 1397-05-11 15:56:28 correct time
in print line date is correct but the time is incorrect. I need this time to my Timepicker
update :
I have listener for time when I change the time set the value on textField
like below :
self.timePickerFrom.addTarget(self, action: #selector(self.dateChangedFrom(_:)), for: .valueChanged). // the listener
and this is what I do for changing value :
let date = self.timePickerFrom.date
print(date)
let components = Calendar.current.dateComponents([.hour, .minute], from: date)
let hour = components.hour!
let minute = components.minute!
self.timeOfloadingLable.text = "\(hour):\(minute)"
but the problem is when I change minute goes 30Min forward
Your are doing it in wrong way, You should set format on date picker not the date of date picker.
Look at this code:
#IBOutlet weak var epoch: UITextField!
#IBOutlet weak var dateTimePicker: UIDatePicker!
#IBAction func presentDate(_ sender: UIButton) {
guard let text = epoch.text else {return}
guard let epoch = Double(text) else {return}
guard let date = convertDate(epoch: epoch) else {return}
dateTimePicker.date = date
dateTimePicker.timeZone = TimeZone(identifier: "IRST")
dateTimePicker.locale = Locale(identifier: "fa_IR")
dateTimePicker.calendar = Calendar(identifier: Calendar.Identifier.persian)
}
private func convertDate(epoch: Double) -> Date? {
let date = Date(timeIntervalSince1970: epoch)
return date
}
Is it what you mean?
I just uploaded a sample project, you can check it here: sample project

myLabel display the wrong name (UIDatePicker)

I have a problem, my label displays the wrong month name after selected from DatePicker.
img app
Code:
let myDatePicker: UIDatePicker = {
let pv = UIDatePicker()
pv.datePickerMode = .date
pv.locale = Locale(identifier: "de_DE")
pv.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
return pv
}()
#objc func datePickerValueChanged(datePicker: UIDatePicker) {
let format = "dd MMM, yyyy"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
let dateValue = dateFormatter.string(from: datePicker.date)
myLabel.text = dateValue
}
let myLabel: UILabel = {
let label = UILabel()
return label
}()
P.S I have an additional question how to set the language of months in DatePicker automatically with regional settings?
I tried (inside myDatePicker) : pv.locale = .current
First question:
You need to "localize" your dateFormatter, using
dateFormatter.locale = datePicker.locale
in your datePickerValueChanged
Second question:
You want to retrieve the correct month names as retrieved from the iPhone settings
Use Locale.autoupdatingCurrent instead of Locale(identifier: "de_DE")
. This gets the user preferred current locale, automatically up-to-date.

DateFormatter Swift 3

So I am creating a contact phonebook app and I am trying to get the keyboard to display as a DateTimePicker.
I have gotten the keyboard to work after some time but I can't seem to get the formatter working correctly.
#IBOutlet weak var datetxt: UITextField!
var datepicker = UIDatePicker()
func createdatepicker() {
datepicker.datePickerMode = .date
let toolbar = UIToolbar()
toolbar.sizeToFit()
let donebutton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneac))
toolbar.setItems([donebutton], animated: true)
datetxt.inputAccessoryView = toolbar
datetxt.inputView = datepicker
}
func doneac() {
let Date = DateFormatter()
Date.dateStyle = .short
//Date.string(from: String)
datetxt.text = "\(datepicker.date)"
self.view.endEditing(true)
}
When I run the app it selects the date but, it also shows the time in the text field.
You're not using your DateFormatter. The datetxt.text = "\(datepicker.date)" simply sets the text to the description of the date picker's date (which includes date and time). But you're not using your formatter at all.
And, by the way, I wouldn't use Date for the name of the date formatter. One would generally use formatter or dateFormatter. Date only invites confusion with the Swift type of the same name.
Thus, you might do:
let formatter = DateFormatter()
formatter.dateStyle = .short
datetxt.text = formatter.string(from: datepicker.date)
here you can make use of formatter you had not showed any date formatter you used
//here is current date
let date = Date()
//formatter to return value as 21-11-2017
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
//Date Output
let result = formatter.string(from: date)
//second formatter to return time format like 2:31 Am
let formatter1 = DateFormatter()
formatter1.dateFormat = "h:mm a"
//Time Output
let result1 = formatter1.string(from: date)
//set values for example using label for reference
DateLabel.text = result
TimeLabel.text = result1
//actual output is as Follows:
DateLabel = 21-11-2107
TimeLabel = 9:54 AM

How to set a specific default time for a date picker in Swift

Is there any way to set a date picker to display a specific time on load? I have four date picker instances initiated from four text fields for Start Time, Finish Time, Start Date and Finish Date using the squimer/datePickerDialog subclass from GitHub that pops up in a UIAlertView.
In my app a default start time would be 7:00 AM and a default finish time would be 5:00 PM and let the user adjust around those times.
All I can see is that you can set the datePicker.defaultDate to currentDate, minimumDate or maximumDate and only once. Is it possible set the defaultDate to hardcoded strings of sTime = "07:00" and fTime = "17:00" in my calls from the ViewController?
Any help would be appreciated.
EDIT: This is how I am calling the subclass from my viewController
#IBAction func setFT(sender: UITextField) {
resignKeyboardCompletely(sender)
DatePickerDialog().show("Pick a Finish Time", doneButtonTitle: "Done", cancelButtonTitle: "Cancel", datePickerMode: .Time) {
(timeFinish) -> Void in
self.dateFormatter.dateFormat = "HH:mm"
let finTime = self.dateFormatter.stringFromDate(timeFinish)
self.finishTime.text = finTime
}
defaults.setObject(finishTime.text, forKey: "finishTime")
print(finishTime.text)
}
Note that throughout this I am also trying to maintain persistence through NSUser Defaults.
Are you looking for setting the time through a string. If that''s the case you can use a date formatter like this.
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.dateFromString("17:00")
datePicker.date = date
Adding an init to the Picker class
init(time:String) {
super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
setupView()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
if let date = dateFormatter.dateFromString("17:00") {
datePicker.date = date
}
}
Swift 5
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
if let date = dateFormatter.date(from: "17:00") {
print(date) // 2000-01-01 22:00:00 +0000
datePicker.date = date
}
Additional note: If you've already set datePicker.minimumDate and you're using this dateFormat the date/time will default to it's earliest possible date--wasted an hour on this :|
with swift 4+
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.date(from: "17:00")
datePicker.date = date
I got here as it seemed setting the start date wasn't working. Turns out you need to set the initial date after setting the min and max dates.