Error in DataPicker Format - swift

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm "
let selectedDate = dateFormatter.string(from: sender.date)
UserDefaults.standard.set(selectedDate, forKey: "date")
print(selectedDate)
\\method to reload the selected time inside the viewdidLoad func
let selectedDate = UserDefaults.standard.object(forKey: "date")
example.setDate(selectedDate as! Date ?? Date(), animated: false)
But when I run the application it returns this error
Could not cast value of type '__NSCFString' (0x108e8b4f0) to 'NSDate' (0x108e8c0d0).
I converted to HH: mm because I want to record only the time in this format, but I do not know how I'm going to handle it

You should be storing the Date object itself in UserDefaults and not its String representation. In most use cases, it makes more sense to store a Date object, since Date objects represent an absolute point in time and hence you can use them for date comparison or to convert them to local times.
Moreover, it looks like that the setDate function actually expects a Date object and not a String, hence it doesn't make sense to generate a String representation of a Date and then store that in UserDefaults.
//Save the Date object
UserDefaults.standard.set(sender.date, forKey: "date")
//Retrieve the Date object, if it cannot be retrieved, use the current Date
if let selectedDate = UserDefaults.standard.object(forKey: "date") as? Date {
example.setDate(selectedDate, animated: false)
} else {
example.setDate(Date(), animated: false)
}

Andre you save String value in UserDefaults and try to set NSDate from String. If you concern with the time only then my advice to save the date as it is in UserDefaults and get the time as formatted as per as your requirement.
Here are the following steps for saving and retrieving Time :
For saving:
func datePickerChanged(_ sender: UIDatePicker){
UserDefaults.standard.set(sender.date, forKey: "date")
}
For Retrieving:
func getTime(){
let date = UserDefaults.standard.object(forKey: "date") as! Date
let dateFormatter = DateFormatter()
dateFormatter.locale = NSLocale.current
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone! //Set your own time zone here.
dateFormatter.dateFormat = "HH:mm"
print(dateFormatter.string(from: date as Date))
example.setDate(date, animated: false)
}
Hope it will help you and save your time.

Related

Swift string date to date

I read a date from UserDefaults.standard as string in the following format:
"2020-11-06T05:20:20+0100"
I try to convert this string to a date using the following code
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "de_DE")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let dateString: String! = UserDefaults.standard.string(forKey: "timeShared")
let date = dateFormatter.date(from: dateString)
However, the result is always nil. Using let date = dateFormatter.date(from: dateString)! explicitly causes a fatal error.
Any ideas what to do?
Changing the former code to
dateFormatter.dateFormat = "\"yyyy-MM-dd'T'HH:mm:ssZ\""
returns a neatly formatted date subsequently. The error was that the date read from UserDefaults included "".
May be UserDefaults.standard.string(forKey: "timeShared") have no value or the value is not in string format and you are doing force unwrapping in let dateString: String! = UserDefaults.standard.string(forKey: "timeShared") here that making the fatal error.
Better add a conditional if, then use the dateString.
Refer the below code.
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "de_DE")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
if let dateString: String = UserDefaults.standard.string(forKey: "timeShared") {
let date = dateFormatter.date(from: dateString)
print(date)
} else {
print("Data in UserDefaults: \(UserDefaults.standard.string(forKey: "timeShared"))")
}

Compare two date - Swift

How can I convert string like (2019-11-02) without time to date format and get current Date device without time then compare with together?
As well as the above using string representations of date, you can actually work with just the dates themselves. Just converting a the string will give you a "start of day" date. The Calendar has a method which will do the same with a date, allowing you to compare the converted string to 'today'
func isDateToday(dateString: String) -> Bool {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd"
let date = df.date(from: dateString)
let today = Calendar.current.startOfDay(for: Date())
return date == today
}
You can convert the string to date using a dateFormatter then compare with the current date using an if statement
import Foundation
//convert string to date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let myDate = dateFormatter.date(from: "2019-11-02")
//convert today's date in the same formate
let currentFormatter = DateFormatter()
currentFormatter.dateStyle = .short
currentFormatter.dateFormat = "yyyy-MM-dd"
let today = currentFormatter.string(from: Date())
let todayDate = dateFormatter.date(from: today)
//Compare the two date's
if myDate == todayDate {
print("ok")
}

How to store date in userdefaults?

I'd like to record the history of her entry into the textfield. I intend to register this with UserDefaults. But when I try to save it with UserDefaults, "cannot assign value of type 'nsdate'?'to type 'String' " Error. I don't think it's accepting textfield data because it's string. And how can I keep history in memory?
formatteddate and formatteddate2 give this error. The date output is as follows : 20/04/2019 20:23
let token = try? keychain.getString("chipnumbernew")
chip1InfoString = token
var time = NSDate()
var formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy HH:mm"
var formatteddate = formatter.string(from: time as Date)
var formatteddate2 = formatter.string(from: time as Date)
timertextNew.text = formatteddate
timertext2New.text = formatteddate2
let RetrivedDate = UserDefaults.standard.object(forKey: "timertext") as? NSDate
formatteddate = RetrivedDate
let RetrivedDate2 = UserDefaults.standard.object(forKey: "timertext2") as? NSDate
formatteddate2 = RetrivedDate2
If you only want to display the date value you can convert and store it as string otherwise you convert/format it after you have read it, either way you should make sure you use the same type when saving and reading
//save as Date
UserDefaults.standard.set(Date(), forKey: key)
//read
let date = UserDefaults.standard.object(forKey: key) as! Date
let df = DateFormatter()
df.dateFormat = "dd/MM/yyyy HH:mm"
print(df.string(from: date))
// save as String
let df = DateFormatter()
df.dateFormat = "dd/MM/yyyy HH:mm"
let str = df.string(from: Date())
UserDefaults.standard.setValue(str, forKey: key)
// read
if let strOut = UserDefaults.standard.string(forKey: key) {
print(strOut)
}
The following saves a Date object as a Double (a.k.a. TimeInterval). This avoids any date formatting. Formatting can lose precision, and is unnecessary since the string is not intended for users to read.
// save
UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: key)
// read
let date = Date(timeIntervalSince1970: UserDefaults.standard.double(forKey: key))
you can always create an extension for saving and retrieving the date in userdefault. here the example code:
import Foundation
extension UserDefaults {
func set(date: Date?, forKey key: String){
self.set(date, forKey: key)
}
func date(forKey key: String) -> Date? {
return self.value(forKey: key) as? Date
}
}
let userDefault = UserDefaults.standard
userDefault.set(date: Date(), forKey: "timertext")
print(userDefault.date(forKey: "timertext") ?? "")
Your problem is that you are retrieving NSDate from the user default storage and then trying to assign them to a String (formatteddate).
Try this;
formatteddate = formatter.string(from: RetrivedDate as Date)

Swift 4 Date is nil after formatting

I have a date like so:
2014-10-28T00:00:00
and when I try to format it, it returns nil, this is what I tried:
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let closingDate = formatter.date(from: item["closingDate"] as! String)
Why is it returning nil? and How can I fix it?
Drop the millisecond and the timezone from your format:
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

Swift - How to store multiple date in default and retrieve it?

This is my code. I want to save todayString and nextString in user default so that I can display the stored date (update every Tuesday) in label when it's not Tuesday.
let today = NSDate()
let nextTue = Calendar.current.date(byAdding: .day, value: 6, to: today as Date)
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let todayString = formatter.string(from: today as Date)
let nextString = formatter.string(from: nextTue!)
formatter.dateFormat = "dd-MMM-yyyy"
let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
let components = calendar!.components([.weekday], from: today as Date)
if components.weekday == 3 {
print("Hello Tuesday")
thisWeekDate.text! = "\(todayString) - \(nextString)"
} else {
print("It's not Tuesday")
}
NSUserDefaults saves data between runs of apps using the device storage.
The easiest way in your case would be to save two different date objects, or you can create a dictionary containing both date objects and save it instead.
Store
UserDefaults.standard.set(todayString, forKey: "todayStringKey")
Retrieve
let RetrivedDate = UserDefaults.standard.object(forKey: "todayStringKey") as? NSDate
Remove - in case you want to delete it completely from storage
UserDefaults.standard.removeObject(forKey: "todayStringKey")