Convert string with ordinal format to date on iOS - ios

Possible Duplicate:
Converting a string to an NSDate
I have date in string and want to convert in NSDate. In string date is:
"21st June 2012"
How can I convert this in NSDate?
Please concentrate on day "21st" not "21" when you give answer.

You can use NSDateFormatter to change NSString to NSDate.

There is a generic answer for this kind of questions available on Stack Overflow, it's to use NSDateFormatter in Objective-C / DateFormatter in Swift. And the format is following tr35-19 or newer according to Use Format Strings to Specify Custom Formats.
But to deal with your variation of a date format, here is the Swift answer for your specific requirements:
// Your example
let dateString = "21st June 2012"
// Sanitizing input for 2nd, 3rd, 4th
let normalizedDateString = dateString.replacingOccurrences(of: "nd", with: "st").replacingOccurrences(of: "rd", with: "st").replacingOccurrences(of: "th", with: "st")
// Converting string to date object
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US")
formatter.dateFormat = "d'st' MMMM yyyy"
let date = formatter.date(from: normalizedDateString)
Same logic in Objective-C.

Related

DateTime2 formart conversion to Swift Date

I have a date string coming from back-end as "2022-08-16T13:44:11.8743234". Date formatting and conversion is the oldest skill in the book but I cannot figure out why I'm unable to convert that string to a Date object in Swift iOS. I just get nil with any source format I specify.
private func StringToDate(dateString: String) -> Date?
{
let formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-DDTHH:mm:ss.[nnnnnnn]"
let date = formatter.date(from: dateString)
return date //this is nil every time
}
DateTime2 is a more precise SQL Server extension of the normal C# DateTime, hence why the date string has 7 decimal places afters the seconds.
What am I doing wrong?
In your code the way you are handling the millisecond part is wrong. We use usually .SSS for milliseconds. Take a look at here it shows all the symbols related to date format.
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
let date = dateFormatter.date(from: "2022-08-16T13:44:11.8743234")
print(date)
In addition to that you are using DD for day. DD means the day of the year(numeric). So it should be dd. Same case is applied for the year as well.

What is the correct date format for this date-as-a-string? [duplicate]

This question already has answers here:
How to convert "2017-07-11T06:52:15.948Z" in to like "JUL, 7 2017" in swift
(1 answer)
How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift?
(13 answers)
Closed 1 year ago.
The back end is providing me with this date-as-a-string: 2021-09-10T12:57:01.671Z
I need to convert that string to a Date using the iOS DateFormatter; and to do so I need to set the formatter's dateFormat property.
I have tried all sorts of combinations, with no luck. Specifically I am struggling with the .671Z part.
What is the correct date format to use?
You need "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" as date format
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
guard let date = dateFormatter.date(from: self) else {
// fallback if date is not in correct format
return nil
}

Formatting a date from a string in swift [duplicate]

This question already has answers here:
How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift?
(13 answers)
Closed 3 years ago.
i have the following date coming from a server 2019-09-05T10:37:49.494Z as a string and i need to parse this and convert it to a format like this Fri September 13,2019 12:36 AM and back to a string again:
i found multiple question links but none of them are working for me Question One
Question Two
it tried doing this:
let dateFormatterGet = DateFormatter()
let dateFormatterPrint = DateFormatter()
var rawDate = "2019-09-05T10:37:49.494Z"
dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatterPrint.dateFormat = "E, d MMM yyyy HH:mm"
var formattedDate = "Error Formatting date"
if let date = dateFormatterGet.date(from: rawDate) {
formattedDate = dateFormatterPrint.string(from: date)
print("Formatted Date : \(formattedDate)")
}else {
print("There was an error decoding the string")
}
this fails printing the error message, what am i doing wrong and how can i fix it?
You are almost there.
A small tip playing with (NS)DateFormatter put the dateFormat above/under the date string.
yyyy-MM-dd'T'HH:mm:ssZ
2019-09-05T10:37:49.494Z
Then, add "spaces" to align and separate them.
yyyy - MM - dd 'T' HH : mm : ss Z
2019 - 09 - 05 T 10 : 37 : 49 . 494Z
^ ^^^
I highlighted the missing ones. You need to tell the (NS)DateFormatter through the dateFormat how to interpret theses additional characters.
Let's check the documentation.
It's
Fractional Second - truncates (like other time fields) to the count of letters. (example shows display using pattern SSSS for seconds value 12.34567)
So using yyyy-MM-dd'T'HH:mm:ss.SSSZ should interpret them and fix your issue.
That's how you fix your issue. And it explained your error.
But since as pointed by #Zombie it's using a ISO format, use if available the ISO8601DateFormatter if possible (iOS10+)
If in future cases you don't have an ISO something format, you can use theses tips ;)
The format you provided seems like an iso 8601 date for this reason I would suggest using the ISO8601DateFormatter
You can specify the options to match your string
here is an example
let dateString = "2019-09-05T10:37:49.494Z"
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [
.withDashSeparatorInDate,
.withFullDate,
.withFullTime,
.withFractionalSeconds,
.withColonSeparatorInTime
]
// "Sep 5, 2019 at 12:37 PM"
let date = formatter.date(from: dateString) ?? Date()
//"Thursday, September 5, 2019 at 12:37:49 PM"
let formattedDate = DateFormatter.localizedString(
from: date,
dateStyle: .full,
timeStyle: .medium
)
The problem is you don't tell dateFormatterGet how to parse milliseconds. Modify the dateFormat to:
dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

Swift NSDate ISO 8601 format

I am working on date formats in Swift and am trying to convert a string date to NSDate and an NSSate to string date (ISO 8601 format).
This is my code
let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" // ISO 8601
let date = dateFormatter.dateFromString(stringDate)
print("Date = \(date)") // Output is 2016-05-14 16:30:00 +0000
// Again converting it date to string using stringFromDate
print("\(dateFormatter.stringFromDate(date!))") // 2016-05-14T09:30:00.000Z
I am trying to understand why I am getting NSDate in GMT format (adding 7 hours to time 09:30 to 16:30)?
If I convert that NSDate date variable to string, then I am getting the original string date. What is happening here?
You can use NSISO8601DateFormatter or ISO8601DateFormatter for Swift 3.0+
Your format string was wrong. You indicate a literal Z instead of "Z as zulu time". Remove the single quotes:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
You should always specified the locale as en_US_POSIX when parsing Internet time. This is so commonly overlooked that Apple created the ISO8601DateFormatter class in OS X v10.12 (Sierra).
If you're targeting iOS 11.0+ / macOS v10.13+ (High Sierra), you can simply use ISO8601DateFormatter with the withInternetDateTime and withFractionalSeconds options, like so:
let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format
let iso8601DateFormatter = ISO8601DateFormatter()
iso8601DateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = iso8601DateFormatter.date(from: stringDate)
print("Date = \(date)") // Output is 2016-05-14 09:30:00 +0000
For working with DateFormatter on older systems, see Apple Tech Note QA1480:
if you're working with fixed-format dates, you should first set the
locale of the date formatter to something appropriate for your fixed
format. In most cases the best locale to choose is "en_US_POSIX", a
locale that's specifically designed to yield US English results
regardless of both user and system preferences. "en_US_POSIX" is also
invariant in time (if the US, at some point in the future, changes the
way it formats dates, "en_US" will change to reflect the new
behaviour, but "en_US_POSIX" will not), and between machines
("en_US_POSIX" works the same on iOS as it does on OS X, and as it it
does on other platforms).
Here is a snippet of Swift 5, based on the sample code provided:
let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format
let rfc3339DateFormatter = DateFormatter()
rfc3339DateFormatter.locale = Locale(identifier: "en_US_POSIX")
rfc3339DateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
rfc3339DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let date = rfc3339DateFormatter.date(from: stringDate)
print("Date = \(date)") // Output is 2016-05-14 09:30:00 +0000

Is it possible to add custom text in NSDateFormatter's format string?

Suppose I want the date to look like this:
|1988|December|30|
How can add these to the dateFormatter or for that matter let the format be something like this:
30 in the month of December in the year of 1998
now for 1988,December and 30, I would like to use standard formats but I want the text I put to also accompany them.
specially in case of the above one where, in the format and pipes just come adjacent to the date format for date or month where there is no space between the format and the pipe.
Is any of this possible by just setting the format ?
You can insert arbitrary text (enclosed in single quotes) in the date format, for example.
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:#"dd' in the month of 'MMMM' in the year of 'yyyy"];
NSString *s = [fmt stringFromDate:[NSDate date]];
Result:
09 in the month of July in the year of 2013
Swift Version:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE' text here 'h:mm' and there 'a"
Updated for iOS 13, Swift 5, Xcode 11 and building on Martin R's answer
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = Locale.current
dateFormatter.dateFormat = "dd' in the month of 'MMMM' in the year of 'yyyy"
let stringDate = dateFormatter.string(from: Date())
print(stringDate)
// printed:
// 7 in the month of October in the year of 2019
P.S. If you wanted an apostrophe, then use: '' directly inside the string. For example "MMM d, ''yy" -> Nov 10, '19
Extension:
If you wanted to add ordinal indicators too (ex. the 'th' after '13th'), you can actually do it inside the date formatter string.
So if you wanted Nov 10th, the code would be:
/// Get date.
let date = Date()
/// Get just the day of the date.
let dayAsInt = Calendar.current.component(.day, from: date)
/// Init the formatter.
let dateFormatter = DateFormatter()
/// Set the format string.
/// Notice we include the 'MMM' to extract the month from the date, but we use a variable to get the 'th' part.
dateFormatter.dateFormat = "MMM '\(dayAsInt.getStringWithOrdinalIndicatorIfPossible)'"
let formattedDate = dateFormatter.string(from: date)
/// Will print out Nov 10th or Apr 1st or whatever.
Here's the extension I made to help:
/// This variable only adds the ordinal indicator if the Int that is calling this function can be converted to an NSNumber.
/// An ordinal indicator is the `rd` after `3rd` or the `st` after `1st`.
var getStringWithOrdinalIndicatorIfPossible: String {
let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
}

Resources