Actual string - January 31, 2020 at 11:59:59 p.m. (ET).
format - "MMMM d, yyyy 'at' hh:mm:ss aa"
Not able to convert this string to Date object. Tried various date format and but unable to change string to Date object.
Please help

- 274,689
- 30
- 353
- 361

- 651
- 5
- 16
-
Can you show what have you tried so far? – Rob Feb 05 '20 at 12:12
-
@Rob Tried changing timezone, locale, calendar everything – Sumit Jangra Feb 05 '20 at 12:13
-
No @Afsaredrisy ,i already mentioned this string value which need to convert into date object. – Sumit Jangra Feb 05 '20 at 12:14
-
I think "p.m. (ET)" part of your input string is not understandable to DateFormatter. That's why it is unable to convert this string to Date object. – Rameez Feb 05 '20 at 12:16
-
are you sure p.m. is needed? – Salman Ghumsani Feb 05 '20 at 12:17
-
@Rameez i tried after removing pm and ET both but still not able to get the object of Date – Sumit Jangra Feb 05 '20 at 13:26
-
@SumitDhariwal If you removed pm and ET from your input string then your date format should be like this "MMMM d, yyyy 'at' hh:mm:ss". – Rameez Feb 05 '20 at 13:35
2 Answers
You could delete the non-standard character .
between p
and m
and escape the parentheses around the time zone
let dateString = "January 31, 2020 at 11:59:59 p.m. (ET)"
let trimmedDateString = dateString.replacingOccurrences(of: ".m.", with: "m")
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMMM d, yyyy 'at' hh:mm:ss a (v)"
let date = formatter.date(from: trimmedDateString)

- 274,689
- 30
- 353
- 361
-
It would be easier to set a custom am and pm symbols `formatter.pmSymbol = "p.m."` https://stackoverflow.com/a/31469237/2303865 – Leo Dabus Feb 05 '20 at 12:34
-
-
-
What about using `NSDataDetector`? We wouldn't have to use the p.m. & p.m & the parenthesis... – Larme Feb 05 '20 at 12:53
-
In playground i can convert this string to date object but in project i can't. Also pm am ET i removed them all but still datestring not convert into date object. – Sumit Jangra Feb 05 '20 at 13:27
-
@SumitDhariwal don't remove the timezone from your string. If you escape it the timezone will be ignored when parsing your date. – Leo Dabus Feb 05 '20 at 13:32
let raw = "January 31, 2020 at 11:59:59 p.m. (ET)"
func getDateFrom(_ raw: String) -> Date? {
if let i = (raw.range(of: "(")?.lowerBound) { // get index of open parenthesis
var zone: TimeZone?
let dateString = String(raw.prefix(upTo: i)) // January 31, 2020 at 11:59:59 p.m.
let zoneString = String(raw.suffix(from: i)) // (ET)
switch zoneString { // determine time zone
case "(ET)", "(EST)", "(EDT)": // study your data source and learn how they may express time zones
zone = TimeZone(abbreviation: "EDT")
default:
return nil // failure
}
let formatter = DateFormatter()
formatter.dateFormat = "MMMM d, yyyy 'at' hh:mm:ss a"
formatter.timeZone = zone
formatter.amSymbol = "a.m."
formatter.pmSymbol = "p.m."
if let date = formatter.date(from: dateString) {
return date
} else {
return nil
}
} else {
return nil
}
}
if let date = getDateFrom(raw) {
print(date) // 2020-02-01 04:59:59 +0000
}
This should be a good starting point. There are a number of ways to do this, such as whether you want it to fail if a time zone can't be determined, how to extract the time zone (using abbreviations, identifiers, seconds from GMT), etc. I like vadian's answer if I was completely comfortable with the time zone. But time zones are so inconsistent and surprisingly non-standardized when expressed as strings, that I'd rather dedicate a mechanism to getting it and making sure it's valid.
That said, this is a relatively crude example of where I'd begin—a finished version would be more nuanced. In this example, if the time zone fails, the function fails.

- 11,654
- 3
- 38
- 51