DateFormater error only when running on iOS 13 - ios

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

Related

Swift: Local Date object and local timezone

I've searched and searched, but most of the time posts talk about creating a localized string from a Date(). I need a date object to set a Timer to fire at the correct time.
I realize I might be missing something... This is the best I have so far:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy"
dateFormatter.locale = Locale.current
dateFormatter.timeZone = TimeZone.current
let todayDate = dateFormatter.date(from: "05/21/18")!
print(todayDate)
Which outputs:
2018-05-21 07:00:00 +0000
> Question: Why is there the +0000 if I set the dateFormatter variable timeZone to .current?
+ Update 01:
Following #MadProgrammer's comments:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy HH:mm:ss z"
dateFormatter.locale = Locale.current
dateFormatter.timeZone = TimeZone.current
let dateString = dateFormatter.string(from: Date())
let todayDate = dateFormatter.date(from: dateString)!
print(dateString)
print(todayDate)
Which Outputs, first one being correct:
05/21/18 19:29:19 PDT
2018-05-22 02:29:19 +0000
> Question: Why would creating a date from the dateFormatter.string(...) date object be so different?
Thank you in advance!

How to format a date using timezone in Swift?

I have checked other questions but none of them helped me much.
I have following string:
let dateString = "2018-04-29T21:00:00.000Z"
I have successfully converted it to date using the following:
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let convertedDate = dateFormatter.date(from: dateString)
But now I only want the time "hh:mm a" using timezone such as "+8". I have tried following way but it's not working:
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "UTC+8")
dateFormatter.dateFormat = "hh:mm a"
let requiredTime = dateFormatter.string(from: convertedDate!)
Can anyone help me to overcome this problem?
The format you want is hh:mm a Z, which will provide the +0800.
You want to create a TimeZone which +8 hours from GMT, normally I prefer to use the appropriate abrivations (ie AET), but I guess if you don't have that, you can create a TimeZone using secondsFromGMT, for example...
let tz = TimeZone(secondsFromGMT: 8 * 60 * 60)
let toFormatter = DateFormatter()
toFormatter.timeZone = tz
toFormatter.dateFormat = "hh:mm a Z"
let requiredTime = toFormatter.string(from: convertedDate!)
Which based on your example data, will produce a value of...
05:00 AM +0800

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"))

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))")
}

swift NSDate AM and Pm Format [duplicate]

This question already has answers here:
NSDateFormatter- stringFromDate not returning AM/PM
(6 answers)
Closed 5 years ago.
To convert date and time, I have used this:
let formatter = NSDateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
formatter.dateFormat = "M/dd/yyyy, h:mm"
formatter.AMSymbol = "AM"
formatter.PMSymbol = "PM"
let dateString = formatter.stringFromDate(model.courseDate)
print(dateString)
If the course date is "courseDate = "2017-01-09 01:00:00 +0000";"
but I am getting like this in print:
1/09/2017, 1:00 with no any AM or PM.
How can I achieve this?
Thanks.
according to the date formatter specs
You can retrieve a date in 24h format instead of requesting AM/PM by using
HH instead of hh
so the date "21/11/2016 01:30" (pm) would be "21/11/2016 13:30".
if you do need to print the format, though, you can print it using:
a
More date fomatting details here
As per Apple general date formatter you should use "M/dd/yyyy, hh:mm a" in your date format.
like : formatter.dateFormat = "M/dd/yyyy, hh:mm a"
Hope this will help you!
use following code may help full for you
//Call function
let dateTime = self.convertDateFormaterAamer(sendTimeStep, inputDateFormate: "dd-MM-yyyy HH:mm:ss", outputDateFormate: "dd-MMM-yyyy hh:mm a")
//Date function
func convertDateFormater(date: String,inputDateFormate: String , outputDateFormate: String) -> String
{
let dateFormatter = NSDateFormatter()
//dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
//dateFormatter.timeZone = NSTimeZone(name: "UTC")
dateFormatter.dateFormat = inputDateFormate
let date = dateFormatter.dateFromString(date)
//dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"
//dateFormatter.timeZone = NSTimeZone(name: "UTC")
dateFormatter.dateFormat = outputDateFormate
var timeStamp = ""
if (date != nil)
{
timeStamp = dateFormatter.stringFromDate(date!)
}
return timeStamp
}

Resources