DateFormatter not working Swift with Hour and minute second - ios

Getting nil converting date string to date
func convertDateFormater(dateStr: ""2022-10-22T22:22:16:2216Z"") -> String? {
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let strSelected = inputFormatter.date(from: dateStr)
}
convertDateFormater(dateStr: "2022-10-23T00:00:00.000Z") // Working fine
***convertDateFormater(dateStr: ""2022-10-22T22:22:16:2216Z"") // Not Working fine getting nil***
Should work convertDateFormater(dateStr: ""2022-10-22T22:22:16:2216Z"")

There are many issues in this code
"" … "" is invalid syntax.
There is no parameter type defined.
Nothing – or even the wrong type – is returned.
Z is a format specifier, it must not be wrapped in single quotes.
Apart from that look at your date string. A colon between seconds and milliseconds is very uncommon but it works with this code
func convertDateFormater(dateStr: String) -> Date? {
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss:SSSZ"
return inputFormatter.date(from: dateStr)
}
convertDateFormater(dateStr: "2022-10-22T22:22:16:2216Z")
But you cannot convert both strings (colon and period separator) with the same date format.
To do so you need a second parameter
func convertDateFormater(dateStr: String, hasColonMillisecondSeparator: Bool = false) -> Date? {
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = hasColonMillisecondSeparator ? "yyyy-MM-dd'T'HH:mm:ss:SSSZ" : "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return inputFormatter.date(from: dateStr)
}
convertDateFormater(dateStr: "2022-10-23T00:00:00.000Z")
convertDateFormater(dateStr: "2022-10-22T22:22:16:2216Z", hasColonMillisecondSeparator: true)

Related

Date formatting in Swift that supports iOS 13+

I bet this is simple. I'm trying in Xcode playgrounds to play with getting a string date
let string = "2022-11-27 00:00:00 +0000"
and converting that into a Date object that's formatted like DD-MM-YYYY
func airdateFormat(_ key: String) -> Date? {
let expectedFormat = Date().formatted(.dateTime.day().month(.wide).year())
let date = try! Date(strategy: expectedFormat)
return date
}
I also tried
func airdateFormat(_ key: String) -> Date? {
guard let dateString = self[key] as? String else { return nil }
let dateFormatted = DateFormatter.dateFormat(fromTemplate: "MM-DD-YYYY", options: Int, locale: Locale?)
return dateFormatted().date(from: dateString)
}
}
I'm parsing this Date string from json hence the guard/else statement
You need to use a format that matches your input to parse the string to a Date
If you want to use the DateFormatter
let string = "2022-11-27 12:34:56 +0000"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let date = formatter.date(from: string)
and for recent OS versions you use a FormatStyle
let formatStyle = Date.FormatStyle()
.year(.defaultDigits)
.month(.twoDigits)
.day(.twoDigits)
.hour()
.minute()
.second()
.timeZone()
let date = try formatStyle.parse(string)

Swift how to convert date format [duplicate]

This question already has answers here:
Date Format in Swift
(24 answers)
Closed 2 years ago.
I have a date of type date and has a format "yyyy-MM-dd HH:mm:ss" and I would like to convert it to "yyyy-MM-dd". I am not sure how to achieve this since the date is of type Date.
Example :
let dateComponents: Date? = dateFormatterGet.date(from: "2019-03-11 17:01:26")
Required output :
Date object of format type "yyyy-MM-dd"
It is important to note that I have only date objects and no string.
You have a date of type String, not Date.
You use one DateFormatter to convert it to Date (check that the DateFormatter doesn't return nil).
Then you use another DateFormatter to convert the Date to a string.
Please don't use "dateComponents" as a variable name. You never, ever touch date components in your code. And you don't need to specify the type, just "let date = ..." or better "if let date = ..." checking for nil.
you can use like this:
let now = Date().UTCToLocalDateConvrt(format: "yyyy-MM-dd HH:mm:ss",convertedFormat : "yyyy-MM-dd")
put below function in Date extension class:
extension Date {
func UTCToLocalDateConvrt(format: String,convertedFormat: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let timeStamp = dateFormatter.string(from: self)
dateFormatter.dateFormat = convertedFormat
guard let date = dateFormatter.date(from: timeStamp)else{
return Date()
}
return date
}
}
func formatDate(yourDate: String) -> String { // "yyyy-MM-dd HH:mm:ss"
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss" // here you can change the format that enters the func
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "yyyy-MM-dd" // here you can change the format that exits the func
if let date = dateFormatterGet.date(from: yourDate) {
return dateFormatterPrint.string(from: date)
} else {
return nil
}
}
use it like this:
formatDate(yourDate: "2019-03-11 17:01:26")
it will return an optional string, that can be nil, make sure you are safety unwrap it (if let , guard let)
answer based on link

Using DateFormatter to parse this string into a Date?

I'm hitting a webservice that is returning a string in the following format:
"yyyy-MM-dd'T'HH:mmZ"
It's very close to the standard UTC format, but just without the ss at the end. My issue is that my dateFormatter is always returning nil...and I have tried to make sure that locale and everything else is setup properly.
Here is an example of an actual string:
2019-12-26T00:00Z
Here is the code that creates the DF:
extension DateFormatter {
#objc static func defaultDateFormat(_ format: String) -> DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "US")
formatter.dateFormat = format
return formatter
}
func date(from string: String?) -> Date? {
if let string = string {
return self.date(from: string)
} else {
return nil
}
}
func string(fromOptional date: Date?) -> String? {
if let date = date {
return self.string(from: date)
} else {
return nil
}
}
func string(fromOptional date: Date?, defaultStr: String) -> String {
return self.string(fromOptional: date) ?? defaultStr
}
}
let df = DateFormatter.defaultDateFormat("yyyy-MM-dd'T'HH:mmZ")
let date: Date? = df.date(from: __dateString__) // always nil
A few observations:
You want to use a locale of en_US_POSIX, an invariant locale that always works for ISO 8601 / RFC 3339 date strings. See Technical Q&A 1480.
If you want to use this formatter to convert a date back to a string like 2019-12-26T00:00Z, you will want to:
Use X (or ZZZZZ or XXXXX) in your format string, not Z (see the “zone” section in the table at Date Format Patterns and you’ll see how these various time zone patterns, e.g. Z, ZZZZZ, and X, are interpreted); and
Set the timeZone of the formatter to use Zulu/GMT/UTC.
Thus:
#objc static func defaultDateFormat(_ format: String) -> DateFormatter {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = format
return formatter
}
And
let df = DateFormatter.defaultDateFormat("yyyy-MM-dd'T'HH:mmX")
let date = df.date(from: "2019-12-26T00:00Z")
Or
let string = df.string(from: Date())

How to check if value is datestring or double in Swifty json?

I am parsing json using Swifty json. Now i have a key as "create_date" which can have a timestamp & as well as a date string like "2017-08-17 20:00:00".Now i am not sure when it will be a string date or it is a timestamp.I am using below code to parse this
if let timeInterval = dic?["created_at"].doubleValue {
print("timeinterval is \(timeInterval)")
date1 = NSDate(timeIntervalSince1970: (timeInterval / 1000))
date = self.getStrDateFromDate(dob: date1!) as String
}
if use dict["create_date"].doubleValue so if it a string date then it r return me 2017 & in case of timestamp it return some timestamp as 15383673563465 .
Now how do i identify if is a date or a timestamp ?
Use optional binding and cast down the value to Double with the double property of SwiftyJSON. If the downcast succeeds create the string from the Date otherwise use the date string directly.
let dateString : String
if let timeInterval = dic?["created_at"].double {
print("timeinterval is \(timeInterval)")
date1 = Date(timeIntervalSince1970: timeInterval / 1000)
dateString = self.getStrDateFromDate(dob: date1!) as String
} else {
dateString = dic?["created_at"].stringValue
}
Side note:
Why do you (bridge) cast a result to string (from getStrDateFromDate) which is supposed to be a string?
I would try a DateFormatter with the format of your possible date string, then try to convert it to a double. Or vise-versa. The order really doesn't matter too much, although it may be slightly less expensive to check for the double first.
import Foundation
func convertDate(dateString:String) -> Date? {
// try `Double`
if let timestamp = Double(dateString) {
return Date(timeIntervalSince1970: timestamp)
}
// try `DateFormatter`
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let date = formatter.date(from: dateString) {
return date
}
// give up
return nil
}
let dateString1 = String(Date().timeIntervalSince1970)
let dateString2 = "2017-08-17 20:00:00"
let dateString3 = "something"
print(convertDate(dateString: dateString1) ?? "unknown")
print(convertDate(dateString: dateString2) ?? "unknown")
print(convertDate(dateString: dateString3) ?? "unknown")
// 2017-08-17 15:15:27 +0000
// 2017-08-18 00:00:00 +0000
// unknown
Note that the default description for a Date uses GMT. In my case it's off by 4 hours, which is why the displayed time is 4 hours different from I entered.

How to convert a date string from Rails into Swift

Please bear with me as I'm new to Swift: I'm writing a little app that calls an API (Rails) which return some data. The problem I'm having is that the date provided by the API comes like this: yyyy-MM-dd'T'HH:mm:sssZ my function expects yyyy-MM-dd'T'HH:mm:ssZ Please note the extra second
Here's my function:
public func dateFromString(date: String, format: String) -> NSDate {
if dateFormatter == nil {
dateFormatter = NSDateFormatter()
}
dateFormatter!.dateFormat = format
return dateFormatter!.dateFromString(date)!
}
On the console, when I try to run the app I get this:
date String "2015-04-13T12:48:23.310Z"
format String "yyyy-MM-dd'T'HH:mm:ssZ"
Any ideas on how I should resolve this?
You can do if you use the SSS as format string, like below.
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"
See also: Date Format Patterns
You can use the following function:
func dateFromate(_ stringTime:String) -> String{
//"2015-04-13T12:48:23.310Z"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
guard let date2 = formatter.date(from: stringTime) else{
return stringTime
}
let date1 = Date()
return date1.offset(from: date2)
}

Resources