Got nil after string to date convertation - swift

I need to convert String simular to "2016-07-10T21:32:20G" to Date.
But for some reason I've got only nil again and again.
I've read an article about date formater. And unfortunately haven't fount an answer there. I found something in the documentation. And documentation tels to read about Unicode Date Format Patterns. And it looks similar to mine.
Probably I missed something =(
My Code example. Unfortunately always get nil.
let lastUpdatedDateString = "2016-07-10 21:32:20"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-mm-dd hh:mm:ss"
let lastUpdated = dateFormatter.date(from:lastUpdatedDateString)
But this code works fine:
let lastUpdatedDateString = "2016-07-10"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-mm-dd"
let lastUpdated = dateFormatter.date(from:lastUpdatedDateString)
I'm testing it in the playground.
In fact I must convert this String("2016-07-10T21:32:20G") to Date.
PS
Anyway, thanks for attention =)

Think it's just the capitalisation in your formatter. Try this ...
let lastUpdatedDateString = "2016-07-10 21:32:20"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let lastUpdated = dateFormatter.date(from:lastUpdatedDateString)

This is what I get with the playground
let lastUpdatedDateString = "2016-07-10T21:32:20"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-ddEEEEEHH:mm:ss"
let lastUpdated = dateFormatter.date(from:lastUpdatedDateString)
print(lastUpdated)
and it prints: Optional(2016-07-10 19:32:20 +0000) (I'm GMT+2)
I don't know what the G stands for so I'm not sure how I can get the last character for the pattern. EEEEE stands for day of the week (1 character)
EDIT: It seems G stand for gregorian calendar
so you can parse the last letter out of the string and add this if it's gregorian calendar (but I suppose this is the default value):
dateFormatter.calendar = Calendar(identifier: .gregorian)
If the letter's a J it's Julian calendar then and you can see this answer to see how to convert gregorian to julian: https://stackoverflow.com/a/12137019/2106940

Related

Did SWIFT DateFormatter.dateFormat formatting change?

I recently noticed my DateFormatter is no longer working with am/pm format. Did Swift recently change "h" and "a" dateFormat symbols? Could it be another setting I may have recently changed and am not seeing?
let formatt = DateFormatter()
formatt.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateDater = formatt.date(from:"2019-03-16 14:00:00")
let formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yy hh:mm a"
let string = formatter.string(from:dateDater!)
print("DateString",string)
Result: DateString 03/16/19 14:00
Unless you prevent it, formatting depends on the user Locale. So it all depends on your regional and date time settings, such as this one:
And this one:
For more info, read https://developer.apple.com/library/archive/qa/qa1480/_index.html

Swift: How to parse date & time string with timezone abbreviation?

I receive a date & time string from a server with an information about a timezone formatted in an unusual way:
2017-05-05T12:24:16.286462Z[UTC]
I would like to use DateFormatter to parse it, but I cannot figure out what date format should I use.
I tried parsing it with "yyyy-MM-dd'T'HH:mm:ss.SSSZ'['R']'" or something quite similar but with no luck.
Here is my code:
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en-US")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ'['R']'"
let date = dateFormatter.date(from: date)
What is the right date format for this string?
OK guys, I figured it out.
The right format is
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z['zzz']'"
zzz is for a timezone abbreviation, while Z[ and ] are treated as a plain text.
An alternative approach with ISO8601DateFormatter. The [UTC] portion is stripped with Regular Expression
let dateString = "2017-05-05T12:24:16.286462Z[UTC]"
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = formatter.date(from: dateString.replacingOccurrences(of: "\\[^\\[+\\]", with: "", options: .regularExpression))

Date function returning incorrect result

I cannot find an equivalent answer that resolves for me eg
Please see the code. I'm formatting an incoming string (item[9]) downloaded from a webservice.
var cal_end_date: Date!
var dateFormatter = DateFormatter()
let tempEndDate = item[9]
print("item[9]", item[9]) // 20190331
print("tempEndDate", tempEndDate) //20190331
dateFormatter.dateFormat = "YYYYMMDD"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone.autoupdatingCurrent
cal_end_date = dateFormatter.date(from:tempEndDate)!
print(#function, "cal_end_date:", cal_end_date!) //2019-01-31 05:00:00 +0000
The end date has the wrong month! I have confirmed this result by running the code in a playground with a fixed date. Am I doing something wrong here? Has something changed in Swift 5?
Thanks
You can always use nsdateformatter.com to check if your dateFormat for your formatter is correct (next to the Examples check Reference which shows you what each letter/letters represent).
In your case, you have to be carefull on dateFormat's case sensitive. Days and years are represented by small letters
dateFormatter.dateFormat = "yyyyMMdd"

Getting string between exact letters by regex in Swift

I have a String in this format: "2019-03-11T17:04:00+0100". I need to convert that string to the one that will be in this format: "03.11 17:04". I already tried some suggestions for instance this one.
As per my comment, this is a task for DateFormatter rather than RegeX. I threw this together in a playground quickly to demonstrate what I mean.
let inFormatter = DateFormatter()
inFormatter.locale = Locale(identifier: "en_US_POSIX")
inFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
let input = "2019-03-11T17:04:00+0100"
let dateFromInput = inFormatter.date(from: input)! // This should be unwrapped properly in your code.
let outFormatter = DateFormatter()
outFormatter.locale = Locale(identifier: "en_US_POSIX")
outFormatter.dateFormat = "MM. dd HH:mm"
let output = outFormatter.string(from: dateFromInput)
print(output) // Prints 03. 11 16:04.
The premise is that you provide a format for which to parse the input string against, this is transcoded to a Date object which you can then transcode to your desired output format with a second DateFormatter.
EDIT:
As pointed out by #user28434, the input you are passing in looks like CET (Central European Time); When I configure the output DateFormatter, I do not specify a time zone so it defaults to my local time zone, GMT (Greenwich Mean Time). This would obviously cause the output to be different based on the location of the user in the world, which should be expected/desired. But it's worth highlighting. You can use outFormatter.timeZone = TimeZone(identifier: "CET") to force a CET output.
You can use DateFormatter instead of regex,
first, convert the given string to a date with the string format,
then convert the resulted date to a string with the desired format.
func convertISO8601DateStringToDate(dateStr: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return dateFormatter.date(from: dateStr)
}
func convertDateToReadableOutput(date: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM.dd HH:mm"
return dateFormatter.string(from: date)
}
you can use these two methods as below:
if let date = stringToDateConverter(dateStr: "2019-03-11T17:04:00+0100") {
print(dateToStringConverter(date: date))
}

Swift date formatting

I'm trying to pull a date string from a button and format is as a date to be store in CoreData.
Here is my code:
let dateStr = setDateBTN.titleLabel?.text
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-YYYY"
let date:NSDate = dateFormatter.dateFromString(dateStr!)!
If I do a println on dateStr I get the following: 03-10-2015. Then if I immediately println on date I get: 2014-12-21 05:00:00 +0000.
Any ideas as to why the actual date is changing when I run it through the date formatter?
NSDateFormatter Class Reference : http://goo.gl/7fp9gl
Date Formatting Guide (Apple) : http://goo.gl/8zRTQl
A common mistake is to use YYYY. yyyy specifies the calendar year whereas YYYY specifies the year (of “Week of Year”), used in the ISO year-week calendar.
Your code should work, as you expect, like this :
let dateStr = setDateBTN.titleLabel?.text
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let date:NSDate = dateFormatter.dateFromString(dateStr!)!