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
Related
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
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))
}
}
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.
How to convert date picker value into String type in Swift 3.0 ?
Right now I have managed to create date picker but the value that appear in textfield is today's date which is 2/8/17, m/d/yy format.
My goal is to convert m/d/yy into String and the date value will be 2017-02-08, yyyy/mm/dd format
The code as below.
Date.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet var dateTxt: UITextField!
let datepicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
displayDate()
}
func displayDate(){
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePick))
toolbar.setItems([doneBtn], animated: false)
dateTxt.inputAccessoryView = toolbar
dateTxt.inputView = datepicker
}
func donePick(){
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .none
dateTxt.text = dateFormatter.string(from: datepicker.date)
self.view.endEditing(true)
}
}
Can anyone help ?
Thanks.
For that you need to set dateFormat property of DateFormatter not the dateStyle and timeStyle.
func donePick(){
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateTxt.text = dateFormatter.string(from: datepicker.date)
self.view.endEditing(true)
}
I have an API that returns data including a timestamp for that record.
In swift I have the timestamp element loaded and converted into a double and can then convert that into time. I want to be able to return the time if the date of the record is today and return the date if the record is not today.
See below:
let unixTimeString:Double = Double(rowData["Timestamp"] as! String)!
let date = NSDate(timeIntervalSince1970: unixTimeString) // This is on EST time and has not yet been localised.
var dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .ShortStyle
dateFormatter.doesRelativeDateFormatting = true
// If the date is today then just display the time, if the date is not today display the date and change the text color to grey.
var stringTimestampResponse = dateFormatter.stringFromDate(date)
cell.timestampLabel.text = String(stringTimestampResponse)
Do I use NSCalendar to see if 'date' is today and then do something?
How do you then localise the time so that its correct for the user rather than server time?
There is a handy function on NSCalendar that tells you whether an NSDate is in today or not (requires at least iOS 8) isDateInToday()
To see it working, put this into a playground:
// Create a couple of unix dates.
let timeIntervalToday: NSTimeInterval = NSDate().timeIntervalSince1970
let timeIntervalLastYear: NSTimeInterval = 1438435830
// This is just to show what the dates are.
let now = NSDate(timeIntervalSince1970: timeIntervalToday)
let then = NSDate(timeIntervalSince1970: timeIntervalLastYear)
// This is the function to show a formatted date from the timestamp
func displayTimestamp(ts: Double) -> String {
let date = NSDate(timeIntervalSince1970: ts)
let formatter = NSDateFormatter()
formatter.timeZone = NSTimeZone.systemTimeZone()
if NSCalendar.currentCalendar().isDateInToday(date) {
formatter.dateStyle = .NoStyle
formatter.timeStyle = .ShortStyle
} else {
formatter.dateStyle = .ShortStyle
formatter.timeStyle = .NoStyle
}
return formatter.stringFromDate(date)
}
// This should just show the time.
displayTimestamp(timeIntervalToday)
// This should just show the date.
displayTimestamp(timeIntervalLastYear)
Or, if you just want to see what it looks like without running it yourself:
Abizern's answer in Swift 3:
import UIKit
let timeIntervalToday: TimeInterval = Date().timeIntervalSince1970
let timeIntervalLastYear: TimeInterval = 1438435830
// This is just to show what the dates are.
let now = Date(timeIntervalSince1970: timeIntervalToday)
let then = Date(timeIntervalSince1970: timeIntervalLastYear)
// This is the function to show a formatted date from the timestamp
func displayTimestamp(ts: Double) -> String {
let date = Date(timeIntervalSince1970: ts)
let formatter = DateFormatter()
//formatter.timeZone = NSTimeZone.system
if Calendar.current.isDateInToday(date) {
formatter.dateStyle = .none
formatter.timeStyle = .short
} else {
formatter.dateStyle = .short
formatter.timeStyle = .none
}
return formatter.string(from: date)
}
// This should just show the time.
displayTimestamp(ts: timeIntervalToday)
// This should just show the date.
displayTimestamp(ts: timeIntervalLastYear)