Getting date from DateFormatter without delimiter(/ or -) returns wrong date: - ios

Getting date from DateFormatter without delimiter returns the wrong date,
As per our requirement, we cannot use / or - in our date formatter string.
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.current
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.calendar = Calendar(identifier: .iso8601)
dateFormatter.dateFormat = "ddMMyyyy"
dateFormatter.date(from: "1112987")
this returns "Nov 1, 2987 at 8:00 AM", however it should be "Dec 11 0987"
Another Example:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMddyyyy"
dateFormatter.date(from: "1131987") // "Jan 13, 1987 at 12:00 AM"
This should return nil as November 31st is a invalid date
Please suggest any solution

You have to update your date format from ddMMyyyy to MMddyyyy.
Your code :-
dateFormatter.dateFormat = "ddMMyyyy"
New code :-
dateFormatter.dateFormat = "MMddyyyy"
Also, you have to set 4 digit year instead of 3 digit.
Your code :-
dateFormatter.date(from: "1112987")
New code :-
dateFormatter.date(from: "11120987"
If you get any issue post your reply.

Related

Convert string containing date to Date

I'm having issues converting a string to date on swift, maybe it is something obvious but I don't get it.
I'm trying to convert "Jan 18, 2022 04:39PM GMT" this string into a Date. My code looks like this:
let str = "Jan 18, 2022 04:39PM GMT"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, YYYY hh:mma z"
let date = dateFormatter.date(from: str)
print(date)
And console shows: Optional(2021-12-19 16:39:00 +0000)
Any idea what's wrong in this formatter?
In addition to the Date being shown as an Optional, your format string appears to be wrong. "YYYY" should be "yyyy", so the whole line that assigns the formatter should be:
dateFormatter.dateFormat = "MMM d, yyyy hh:mma z"
That change yields the output
"Optional(2022-01-18 16:39:00 +0000)"
In addition, you should really force the calendar to Gregorian or iso8601, and set its locale to "en_US_POSIX:
An improved version of the date formatter could would look like this:
(from Leo's edit.)
let str = "Jan 18, 2022 04:39PM GMT"
let dateFormatter = DateFormatter()
dateFormatter.calendar = .init(identifier: .iso8601)
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "MMM d, yyyy hh:mma z"
if let date = dateFormatter.date(from: str) {
let dateString = dateFormatter.string(from: date)
print(dateString == str) // true
}
The code written for converting date is correct, also converted date is correct. But final result is optional so you are getting date like Optional(2021-12-19 16:39:00 +0000).
Also the date formatter is wrong.
So please unwrap the date to get actual date without optional.
dateFormatter.dateFormat = "MMM d, yyyy hh:mma z"
guard let convertedDate = date else {
return
}
print(convertedDate)

DateFormatter returning nil for valid Date in format "dd/MM/yyyy" [duplicate]

I have the below code on playground and app and DateFormatter are returning nil just for the date "1990-10-21":
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd"
let date1 = dateFormatter.date(from: "1990-10-20") // "Oct 20, 1990 at 12:00 AM"
let date2 = dateFormatter.date(from: "1990-10-21") // nil
let date3 = dateFormatter.date(from: "1990-10-22") // "Oct 22, 1990 at 12:00 AM"
Testing with 1989, 2021... works fine...
Does anyone knows why or something about this? is it a bug?
There are three issues with your code. First YYYY is for YearForWeekOfYear. What you need is yyyy. Second you are not passing the time. Note that not all days starts at 12:00am (daylight savings transition dates). You can prevent the date formatter returning nil by setting its calendar or passing a valid time (12pm) along with the date. Third you should always set the locale to "en_US_POSIX" when using a fixed date format:
let dateFormatter = DateFormatter()
dateFormatter.calendar = .current
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"
let date1 = dateFormatter.date(from: "1990-10-20") // "Oct 20, 1990 at 12:00 AM"
let date2 = dateFormatter.date(from: "1990-10-21") // "Oct 21, 1990 at 1:00 AM"
let date3 = dateFormatter.date(from: "1990-10-22") // "Oct 22, 1990 at 12:00 AM"

DateFormater error only when running on iOS 13

I have a function to convert string to date format. This function works as expected on iOS 12 but on iOS 13. I get this error:
"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"
Here is my code:
func ConvertDateAndTimeFormat2() {
let timeDate = "2019-09-24 15:00:00 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss +zzzz"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
var dateObj:Date!
dateObj = dateFormatter.date(from: timeDate)
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss +zzzz"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
var timeObj:Date!
timeObj = timeFormatter.date(from: timeDate)
timeFormatter.dateFormat = "HH:mm"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
let timef = "\(timeFormatter.string(from: timeObj!))"
let Date = "\(dateFormatter.string(from: dateObj!))"
}
Please change your dateformat and use "yyyy-MM-dd HH:mm:ss Z" and try.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
For more details please visit https://nsdateformatter.com/
If you are trying to convert string time which in 24 hours format (Ex 15:25:00 / HH:mm:ss) then enable your device 24-Hour Time option. It might solve the issue in IOS 13.3
You may find the option here
Settings -> General -> Date & Time
There are many issues with your code. There is no reason to create two Date objects from one string. Just parse the original string once. Then you can create your date string and time string with the desired formats from that one date.
You should also use the special locale of en_US_POSIX when parsing fixed format date strings. There is also no need to set a timezone when parsing the original date string. The string provides its own timezone. The +0000 means it is UTC time.
You may not want to provide a timezone when converting the date to your final strings either. Most likely you want strings in the user's locale timezone, not some hardcoded timezone.
Here's your code cleaned up a lot:
func convertDateAndTimeFormat2() {
let timeDate = "2019-09-24 15:00:00 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
if let dateObj = dateFormatter.date(from: timeDate) {
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00") // Probably not needed
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HH:mm"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00") // Probably not needed
let timef = timeFormatter.string(from: dateObj)
let datef = dateFormatter.string(from: dateObj)
print("Date: \(datef), time: \(timef)")
}
}
convertDateAndTimeFormat2()
Output:
Date: Tuesday, Sep 24, 2019, time: 18:00

Swift DateFormatter returning wrong date

I have a issue with getting the correct date in the following case
let dateString = "May 2, 2018 at 3:31 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd, yyyy 'at' HH:mm a"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: dateString)!
I am getting "May 2, 2018 at 8:31 AM" as the date, which is wrong
When the same date is used with a different dateformatting string i get the correct date
let dateFormatter3 = DateFormatter()
dateFormatter3.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter3.locale = Locale(identifier: "en_US_POSIX")
dateFormatter3.timeZone = TimeZone(identifier: "UTC")
let date3 = dateFormatter3.date(from: "2018-05-02T15:31:00")!
Date returned is "May 2, 2018 at 11:31 AM" which is correct.
I like to know what i am doing wrong in the first code block? Or is this a bug in the date formatter class ?
when hour is in am/pm(1~12) use hh, to hour in day(0~23) use HH.
This helps me format my dates:
I hope this would work for you:
let dateString = "May 2, 2018 at 3:31 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd, yyyy 'at' hh:mm a"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: dateString)
print(date!)
Output:-

Converting a full date into just hours and minutes - Swift

I'm trying to do something very simple here and failing miserably. I just want to convert a string with a complete date into just the hours and minutes, can anyone see where I am going wrong? The following code prints nil
let dateString2 = "2018-03-11 20:43:05 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss +zzzz"
dateFormatter.locale = Locale.init(identifier: "en_GB")
let dateObj = dateFormatter.date(from: dateString2)
dateFormatter.dateFormat = "hh:mm"
print("Dateobj: \(dateFormatter.string(from: dateObj!))")
Your dateFormat String is flawed. hh is the 12hour time format, when you clearly receive a 24h time format, for which you need to use HH. Even though zzzz works, +0000 should actually be represented by z. When working with fixed time formats in most cases you should also set the locale to en_US_POSIX.
let dateString2 = "2018-03-11 20:43:05 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss z"
dateFormatter.locale = Locale.init(identifier: "en_US_POSIX")
let dateObj = dateFormatter.date(from: dateString2)
dateFormatter.dateFormat = "HH:mm"
print("Dateobj: \(dateFormatter.string(from: dateObj!))")
Output:
20:43
You need HH (24-hour) for the hour, not hh (12-hour). You also need to use the special locale of en_US_POSIX, not en_GB. You should also use Z for the timezone, not +zzzz.
let dateString2 = "2018-03-11 20:43:05 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
if let dateObj = dateFormatter.date(from: dateString2) {
dateFormatter.dateFormat = "HH:mm" // or "hh:mm a"
print("Dateobj: \(dateFormatter.string(from: dateObj))")
}

Resources