Converting string to date returns nil - swift

I am trying to convert my string to a date using a static date formatter. When I make the call to stringToDate() using the variables below, a nil value is returned.
I've checked previous posts about this issue where people are saying it's because of the dateformatter locale or timeZone. However, that doesn't seem to be the issue in this case.
Does anyone know what the issue could be in this case? My code is below:
import Foundation
class DateHelper {
private static let dateFormatter: DateFormatter = {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
df.locale = Locale(identifier: "en_GB")
df.timeZone = TimeZone.current
return df
}()
static func stringToDate(str: String, with dateFormat: String) -> Date? {
dateFormatter.dateFormat = dateFormat
let date = dateFormatter.date(from: str)
return date
}
}
var myDate = Date()
var dateStr = "2019-02-19T17:10:08+0000"
print(DateHelper.stringToDate(str: dateStr, with: "MMM d yyyy")) // prints nil

Looks like your string is in ISO8601 format. Use the ISO8601DateFormatter to get date instance. You can use ISO8601DateFormatter.Options to parse varieties of ISO8601 formats. For your string,
For Swift 4.2.1
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: dateStr)
print(date!)
Should output
"2019-02-19 17:10:08 +0000\n"

Your date format doesn't match your input date. Try this code:
print(DateHelper.stringToDate(str: dateStr, with: "yyyy-MM-dd'T'HH:mm:ssZZZZZ"))
Hope this helps.

Related

Swift DateTime Formatter returning nil with matching format

When parsing an input datetime string with the matching format, I am still getting nil back from DateFormatter in swift.
Input string (copied at runtime from variable) and confirmed that is the string running the call with Postman.
"2020-06-30T14:41:33.9"
Parsing method
static func FormatDateTimeString(dateTimeString: String) -> String {
let inputDateFormatter = DateFormatter()
inputDateFormatter.dateFormat = "YYYY-MM-DDThh:mm:ss.s"
let date = inputDateFormatter.date(from:dateTimeString) //date is always nil
let outputDateFormatter = DateFormatter()
outputDateFormatter.dateFormat = "MMM d, yyyy HH:mm"
return outputDateFormatter.string(from: date!)
}
I have also tried "YYYY-MM-DD'T'hh:mm:ss.s" and "YYYY-MM-DDThh:mm:ss" but none seem to work.
EDIT: Trying the format suggested below I am still getting nil.
EDIT: As Suggested from the comments I am still getting nil. Format below is: inputDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S"
EDIT: Still getting null using the following config
Use this format:
"yyyy-MM-dd'T'HH:mm:ss.S"
Demo
let dateTimeString = "2020-06-30T14:41:33.9"
let inputDateFormatter = DateFormatter()
inputDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S"
let date = inputDateFormatter.date(from: dateTimeString) // "Jun 30, 2020 at 2:41 PM"

Date format from url (JSON)

How would I be able to take the date format from a URL and turn It into 2 separate date values in SwiftUI. The format from JSON is 2019-11-06 18:30:00 and I'm trying to get it to show as Dec 5 and would also like it to separate the time and show 8:00PM, is this possible?
This is the code that references the start time:
let startTime: String
var startTime: String {
return self.post.startTime
}
Let's step around the fact that 2019-11-06 18:30:00 can't be represented as Dec 5 and 8:00PM and focus on the work flow you'd need.
The basic idea is to:
Convert the String to a Date, via a DateFormatter
Use a custom DateFormatter to format the Date to the required "date" value
Use a custom DateFormatter to format the Date to the required "time" value
This might look something like...
let startTime = "2019-11-06 18:30:00"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let date = formatter.date(from: startTime) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d"
let dateString = dateFormatter.string(from: date)
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "h:ma"
let timeString = timeFormatter.string(from: date)
} else {
print("Bad date/format")
}
In my testing, this outputs Nov 6 and 6:30PM
you can pass your string date to date with this function
func stringToDate(date: String, format: String) -> Date
{
let date2 = date.count == 0 ? getCurrentDate(format: "dd-MM-yyyy") : date
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.init(identifier: "América/Mexico_City")
dateFormatter.dateFormat = format
let dateDate = dateFormatter.date(from: date2)
return dateDate!
}
func getCurrentDate(format: String) -> String
{
let formD = DateFormatter()
formD.dateFormat = format
let str = formD.string(from:Date())
return str
}
let dateA = stringToDate(date: "2019-11-06 18:30:00", format: "yyyy-MM-dd HH:mm:ss")
if dateA < Date() //Date() always will be the current date, including the time
{
print("dateA is older")
}
else
{
print("dateA in newer")
}
play with the format examples formats

dateformat spelling format swift

I am removing the current time from the current time and trying to find the minute difference. But it says 10/09/2019 13:13 and there is an error in the extraction process (I want to print as 1313) .1313 I can perform the extraction process. How do I print this data the way I want? I want to print dateFormat = "HHmm". In timertext2New.text, dateFormat = "dd / MM / yyyy HH: mm" like this. But I want to save it in HHmm format.
save12 output: 05/09/2019 10:48 but I want it to be "1048" . To perform extraction.
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy HH:mm"
timertext2New.text = formatter.string(from: datePicker.date)
let timehafıza2 = String(self.timertext2New.text!)
let df2 = DateFormatter()
df2.dateFormat = "HHmm"
var str2 = df2.string(from: Date())
str2 = timehafıza2
UserDefaults.standard.setValue(str2, forKey: "timertext2")
override func viewDidLoad() {
super.viewDidLoad()
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HHmm"
let hour = dateFormatter.string(from: date)
var save12 = UserDefaults.standard.integer(forKey: "timertext2")
var fark : Int = (Int(hour)! - Int(save12))
}
Your code is pretty confusing and cannot work
You convert a date from a date picker with format "dd/MM/yyyy HH:mm"
Then you create a string with format "HHmm" from the current date which will be destroyed immediately because
You overwrite this string with the dd/MM/yyyy HH:mm string and save it to UserDefaults
Later you read the value from UserDefaults as integer which returns 0 because the "dd/MM/yyyy HH:mm" format is not representable by an integer.
My suggestion is to save all dates as Date and perform the date math with the dedicated methods of Calendar

Swift: Date string only has month and year, can I still produce a date?

I'm porting some old Javascript code to a Swift app, my data-set from my client is a little strange in that they recorded just the month and year of each date, so an installation date string would look like: 2001-05.
In Javascript I can use: var date = new Date("2001-05"); to which it returns: 2001-05-01T00:00:00.000Z zeroing the time/day but maintaining the year and month as expected.
I currently use the below code in Swift:
var date = "2001-05"
func stringToDate(_ date: String) -> Date? {
let df = DateFormatter()
df.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale!
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
return df.date(from: date)
}
print(stringToDate(date))
This always produces a nil output. Is it possible to reproduce the JS behaviour of date-formatting in Swift?
You almost had it, I tested it on playgrounds use it like this(Just changed the "yyyy-MM" part):
var date = "2001-05"
func stringToDate(_ date: String) -> Date? {
let df = DateFormatter()
df.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale!
df.dateFormat = "yyyy-MM"
df.date(from: date)
return df.date(from: date)
}
print(stringToDate(date)!)

How to convert a String to NSdate?

I am trying to convert fajerTime to NSDate. When I compile the project the dateValue is nil. Any idea how to fix this issue?
if prayerCommingFromAdan.id == 0 && prayerCommingFromAdan.ringToneId != 0{
// NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
let fajerTime = "\(prayer0.time[0...1]):\(prayer0.time[3...4])" as String
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
// convert string into date
let dateValue = dateFormatter.dateFromString(fajerTime) as NSDate!
print(dateValue)
var dateComparisionResult:NSComparisonResult = NSDate().compare(dateValue)
if dateComparisionResult == NSComparisonResult.OrderedDescending {
addNotificationAlarm(year, month: month, day: day, hour: prayer0.time[0...1], minutes: prayer0.time[3...4], soundId: prayerCommingFromAdan.ringToneId, notificationBody: "It is al fajr adan")
}
The problem seems be the format of fajerTime. It looks like fajerTime is a time string, e.g. 12:34, whereas the date formatter is configured to accept string containing a month, day and year, e.g. 24-07-2016.
You need to format fajerTime to include the year, month and day, as well as the time. Also configure the date formatter to accept the full date and time.
Assuming prayer0 is an array, you will also need to combine the elements into a string, using joinWithSeparator.
e.g.
let hours = prayer0.time[0...1].joinWithSeparator("")
let minutes = prayer0.time[3...4].joinWithSeparator("")
let fajerTime = "\(month)-\(day)-\(year) \(hours):\(minutes)"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy hh:mm"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
// convert string into date
let dateValue = dateFormatter.dateFromString(fajerTime) as NSDate!
Please follow example (Swift 3):
let dateStr = "2016-01-15 20:10:01 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let myDate = dateFormatter.date(from: dateStr)
Keep in mind:
Date format e.g. "yyyy-MM-dd HH:mm:ss Z" must match the date string pattern
In your case, your date string contains only time, yet, your date
formatter contains only date
When using dateFormatter.date() there is no need to cast it to Date as it returns a Date:
Helpful website for date formats:
http://nsdateformatter.com/