How to parse String date to date object in ios swift? - ios

I am parsing date from server into a custom format :-
This is the date :- "8/9/2017 3:58:00 AM" but it is not parsing into Date object using this format "MM/dd/yyyy hh:mm:ss a" because obviously the month, day and hour is single digit
As per my knowledge it should parse automatically because Android's DateFormat parses the same date.
This is the code snippet i am using :-
func getDateString(_ dateString:String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/dd/yyyy hh:mm:ss a"
let date = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = "dd MMM yyyy"
return dateFormatter.string(from: date!)
}
This function is returning null

Your code should work, although you should also add some error-checking.
Try this (it will run in a Playground):
// returns an empty string "" if the date format is invalid
func getDateString(_ dateString:String) -> String {
var strResult = ""
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/dd/yyyy hh:mm:ss a"
if let date = dateFormatter.date(from: dateString) {
dateFormatter.dateFormat = "dd MMM yyyy"
strResult = dateFormatter.string(from: date)
}
return strResult
}
let dateString = getDateString("8/9/2017 3:58:00 AM")
print(dateString) // prints "09 Aug 2017"
If you change your "source" string to an invalid date/time - such as changing the month from 8 to 18 or the hour from 3 to 13 - you will see the returned value is an empty string.

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)

Get only time from Date

How to get only time from the date with am/pm. Below is my code what I have tried so far:
func changeFormat(str:String) -> String {
let dateFormatter = DateFormatter()
let newDateFormatter = DateFormatter()
// step 1
dateFormatter.dateFormat = "MM/dd/yyyy HH:mm aa" // input format
newDateFormatter.dateFormat = "HH:mm aa" // output format
let date = dateFormatter.date(from: str)!
// step 2
let string = newDateFormatter.string(from: date)
return string
}
Usage:
let strTimeFromDate = changeFormat(str: self.response?.Data[indexPath.row].ADateTime ?? "")
input date:
06/22/2021 2:00 PM
output:
12:45 PM
Getting wrong time return after formatting. Please guide what's wrong with above code
As mentioned by #JoakimDanielson in the comment, you are mixing HH (24 hours format) with hh (12 hours format). Using hh for the dateFormatter (given your input has 02:00 PM) should fix your issue (as long as this input value was captured in the same time zone in which you intend to convert).
In case you are still seeing that the output is not expected, then it is the issue with missing timeZone info in your input. You are trying to convert String > Date > String without specifying an input timeZone & output timeZone. You can try printing these values in your implementation.
print("dateFormatter.timeZone.secondsFromGMT() : \(dateFormatter.timeZone.secondsFromGMT())")
let date = dateFormatter.date(from: str)!
print("parsed date : \(date)")
print("\n ------------------------ \n")
// step 2
print("newDateFormatter.timeZone.secondsFromGMT() : \(newDateFormatter.timeZone.secondsFromGMT())")
let string = newDateFormatter.string(from: date)
print("parsed string : \(string)")
For me it prints following. 19800 / (60 * 60) = 5.5 (+05:30)
dateFormatter.timeZone.secondsFromGMT() : 19800
parsed date : 2021-06-22 06:30:00 +0000
------------------------
newDateFormatter.timeZone.secondsFromGMT() : 19800
parsed string : 12:00 PM
The issue is - for these two conversions to happen correctly - you must specify an appropriate time zone.
String to Date
Date to String
Here's what that implementation could look like. Assuming input is "06/22/2021 2:00 PM +0530"
func changeFormat(str: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: Int(5.5*60*60)) // +05:30
let newDateFormatter = DateFormatter()
newDateFormatter.timeZone = TimeZone(secondsFromGMT: Int(5.5*60*60)) // +05:30
dateFormatter.dateFormat = "MM/dd/yyyy hh:mm aa Z"
newDateFormatter.dateFormat = "hh:mm aa"
let date = dateFormatter.date(from: str)!
let string = newDateFormatter.string(from: date)
return string
}
When you are consuming this date string from your backend server, you should consider using appropriate time zone for it. An example, assuming input is "06/22/2021 2:00 PM +0000" -
func changeFormat(str: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) // Server timeZone (UTC)
let newDateFormatter = DateFormatter()
newDateFormatter.timeZone = TimeZone.current // User's timeZone
dateFormatter.dateFormat = "MM/dd/yyyy hh:mm aa Z"
newDateFormatter.dateFormat = "hh:mm aa"
let date = dateFormatter.date(from: str)!
let string = newDateFormatter.string(from: date)
return string
}
"HH" is for 24h format and "aa" is for 12h format so you can't mix them, so you should use "hh:mm a" instead for both DateTimeFormatter's

Getting date from string with HH:mm time format is not working for Japanese language and region in swift

I am trying to get date from string using DateFormatter(). My phone is set to Japan region, Language to Japanese and time to 12 hour format. My app is set to 24 hour format so that user can select time from custom picker in 24 hour format. The Date string is "11 3月, 2019 15:35". The date formatter is "MMM dd, yyyy HH:mm". But it is not working and returns nil always.
According to iOS 10 bug? NSDate hour description with Japan region and 24-Hour Time off
If i use "MMM dd, yyyy KK:mm" as date format then it works only if the time in string is bellow 12:00. Here is my code below.
static func dateFrom(string: String, timeString: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.short
dateFormatter.timeZone = NSTimeZone.local
dateFormatter.locale = NSLocale.current
/// Check time format
var timeFormat = "KK:mm"
if timeString.containsIgnoringCase(find: AppConstants.am.localizedStringWith()) || timeString.containsIgnoringCase(find: AppConstants.pm.localizedStringWith()) {
timeFormat = "h:mm a"
}
/// Check date for MMDD format
dateFormatter.dateFormat = "MMM dd, yyyy \(timeFormat)"
if let date = dateFormatter.date(from: string) {
return date
}
/// Check date for DDMM format
dateFormatter.dateFormat = "dd MMM, yyyy \(timeFormat)"
if let date = dateFormatter.date(from: string) {
return date
}
return dateFormatter.date(from: string)
}
Please let me know if you found solution for it.
Try setting the calendar on your date formatter:
dateFormatter.calendar = .gregorian

Swift date from string always returns nil

I have a date that is a string that looks like this:
Apr 25 2018 12:00AM
What I am trying to do is convert this date format to yyyy-MM-dd and then convert it back to a string, I have a tried the following:
let formatter = DateFormatter()
formatter.dateFormat = "M dd yyyy h:mm A"
let SLAIssuedFinalGradingDate = formatter.date(from: tableDic["SLAIssuedFinalGradingDate"] as! String)
formatter.dateFormat = "yyyy-MM-dd"
let SLAIssuedFinalGradingDateString = formatter.string(from: SLAIssuedFinalGradingDate!)
But SLAIssuedFinalGradingDate always returns nil, what am I doing wrong?
Your dateFormat for Apr 25 2018 12:00AM is not right. You are using M dd yyyy h:mm A, but format would be MMM dd yyyy hh:mma.
Use this link to check date format.
Code Should be:
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MMM dd yyyy hh:mma"
let SLAIssuedFinalGradingDate = formatter.date(from: tableDic["SLAIssuedFinalGradingDate"] as! String)
formatter.dateFormat = "yyyy-MM-dd"
let SLAIssuedFinalGradingDateString = formatter.string(from: SLAIssuedFinalGradingDate!)
Your dateFormat string is incorrect. A DateFormatter will always return nil if the dateFormat string does not match the supplied string.
"MMM dd yyyy hh:mma"
This is what you're after. I suggest you review a DateFormatter cheat sheet and familiarise yourself with the symbols.

How to get the day of the week from a date in Swift

I can print the date in this format: Mon, Mar 19, 2018, but I am not sure how to get the Day of the week in this format.
Please help
let dateFormatter = DateFormatter()
// uncomment to enforce the US locale
// dateFormatter.locale = Locale(identifier: "en-US")
dateFormatter.setLocalizedDateFormatFromTemplate("EEE MMM d yyyy")
print(dateFormatter.string(from: Date())) // "Tue, Mar 20, 2018" for en-US locale
Note that I am using a template to provide the exact format, therefore the format will be properly localized in every language.
To get the day for a particular date:
let customDateFormatter = DateFormatter()
print(customDateFormatter.weekdaySymbols[Calendar.current.component(.weekday, from: Date())])
// "Wednesday"
source
Rather than needing to spell out a date format. I would simplify it further to:
dateFormatter.dateStyle = .full
Or if you just want the day:
dateFormatter.dateFormat = "EEEE"
With swift 4
func timeStamp()->String {
let dateFormater = DateFormatter()
dateFormater.locale = Locale(identifier: "en-US")
dateFormater.setLocalizedDateFormatFromTemplate("EEE MMM d yyyy")
return dateFormatter.string(from: Date())
}
Use it.
let getTimeStamp = timeStamp()
print(getTimeStamp)
dateFormatter.dateFormat = "EEE, MMM dd, yyyy"
For dat of week in alphabets, you use EEEE or EEE similar to MMM & yyyy for month year.
The best way to change your date is follow this method.
func ChangeDateFormat(date:String,FromFormat: String, ToFormat: String) -> String {
let dateFormatter1 = DateFormatter()
dateFormatter1.dateFormat = FromFormat
let myDate = dateFormatter1.date(from: date)
dateFormatter1.dateFormat = ToFormat
if(myDate != nil){
let Date = dateFormatter1.string(from: myDate!)
return Date
}
else{
return ""
}
}
and then you can use this method like
String(ChangeDateFormat(date: StartDate, FromFormat: "yyyy-MM-dd hh:mm:ss a", ToFormat: "MMM d, yyyy"))
You can pass your date format in which format do you want in your case it should be
String(ChangeDateFormat(date: StartDate, FromFormat: "Pass your date format", ToFormat: "EEE MMM d, yyyy"))

Resources