Swift datefomatter returns wrong time - ios

I am working in iOS app with Dateformatter which is return wrong time. I don't have any idea to fix this. Can anyone please correct me to get correct time?
let dateString = "2020-08-11T05:32:33.000Z"
func approach1(){
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
guard let date = dateFormatter.date(from: dateString) else {fatalError()}
printTime(date: date)
}
func approach2(){
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
guard let date = dateFormatter.date(from: dateString) else { fatalError()}
printTime(date: date)
}
func printTime(date: Date){
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm a"
dateFormatter.amSymbol = "AM"
dateFormatter.pmSymbol = "PM"
let time = dateFormatter.string(from: date)
print("date: \(date)")
print("Time: \(time)") // Here it's always wrong time with those approach.
}
Current Result:

By default dateFormatter works with local time zone. To have correct display set its time zone to UTC : dateFormatter.timeZone = TimeZone(abbreviation: "UTC")

There's nothing wrong. The date formatter returns the correct time
The date string
"2020-08-11T05:32:33.000Z"
represents a date in UTC(+0000).
Your local time zone is obviously UTC+0530. DateFormatter considers the local time zone by default.
To format the time also in UTC you have to set the time zone of the date formatter explicitly
func printTime(date: Date) {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: "UTC")
dateFormatter.dateFormat = "h:mm a"
dateFormatter.amSymbol = "AM"
dateFormatter.pmSymbol = "PM"
let time = dateFormatter.string(from: date)
print("date: \(date)")
print("Time: \(time)")
}

You need to specify the time zone when formatting to string (by default it's using your current local time zone):
func printTime(date: Date) {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "UTC") // <- add here
dateFormatter.dateFormat = "h:mm a"
dateFormatter.amSymbol = "AM"
dateFormatter.pmSymbol = "PM"
let time = dateFormatter.string(from: date)
print("date: \(date)")
print("Time: \(time)")
}

Related

Date to String [format string] String to Date in Swift

I've racked my brain over this issue all day and can't seem to get a solution. I have a fitness program that queries the Health Data Store. In the predicateForSamples(withStart: myStartDate, end: myEndDate) I am finding that getting a date from a datePicker sends a moment in time and therefore my query does not return the results for the entire day as I'd like. So, I figured if I take that datePicker date and convert it to a starting and ending format my issue would be solved. However, using the let date = dateFormatter.date(from: dateString) is returning the correct date but the time returns as 04:00:00 +0000 for both functions.
If anybody has a suggestion, please feel free to lend a helping hand. Thank you so very much!
func convertStartDate(StartDate: Date) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyy-MM-dd '00':'00':'01' +0000"
let dateString = dateFormatter.string(from: StartDate)
print("convertingStartDate() - \(dateString)")
let date = dateFormatter.date(from: dateString)
print(date as Any)
return date!
}
func convertEndDate(EndDate: Date) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyy-MM-dd '23':'59':'59' +0000"
let dateString = dateFormatter.string(from: EndDate)
print("convertingEndDate() - \(dateString)")
let date = dateFormatter.date(from: dateString)
return date!
}
This should fix your issue
func convertStartDate(StartDate: Date) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "yyy-MM-dd '00':'00':'01' +0000"
let dateString = dateFormatter.string(from: StartDate)
dateFormatter.dateFormat = "yyy-MM-dd HH:mm:ss +0000"
let date = dateFormatter.date(from: dateString)
print(date as Any)
return date!
}
func convertEndDate(EndDate: Date) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "yyy-MM-dd '23':'59':'59' +0000"
let dateString = dateFormatter.string(from: EndDate)
dateFormatter.dateFormat = "yyy-MM-dd HH:mm:ss +0000"
let date = dateFormatter.date(from: dateString)
return date!
}
In addition to above, this is actually fixed by setting dateFormatter.timeZone = TimeZone(secondsFromGMT: 0), as the seconds from GMT is your issue.

DateFormatter from "24:00" string returns Nil

I cannot seem to figure out why only "24:00" returns nil instead of 12:00AM, whereas "23:59" returns correctly as 11:59PM.
let dateAsString = "24:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
let date = dateFormatter.date(from: dateAsString)
dateFormatter.dateFormat = "h:mm a"
let Date12 = dateFormatter.string(from: date!)
print(Date12)
You are using the wrong date format for the hour component. For values from 1-24 you have to use k, if you have a leading zero you need to use kk:
let dateAsString = "24:00"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "kk:mm"
if let date = dateFormatter.date(from: dateAsString) {
dateFormatter.dateFormat = "h:mm a"
let date2 = dateFormatter.string(from: date)
print(date2) // "12:00 AM\n"
}

IOS conversion of UTC to local time not accurate

I'm trying to convert a UTC to device local time in Swift 4. I found many solutions on stackoverflow for that and I implemented them in my code. My code works fine but it doesn't return the right answer.
My code is:
func UTCToLocal() -> String {
let a = "2:36:27 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm:ss aa"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: a)
dateFormatter.timeZone = TimeZone.current
dateFormatter.defaultDate = Date()
dateFormatter.dateFormat = "hh:mm:ss aa"
return dateFormatter.string(from: dt!)
}
According to my local time, Lebanon, this method should return the value 5:36:27 PM. However, it is returning 4:36:27 PM.
Note: I checked my device's local time and it's set correctly
This is due to Daylight Saving Time in Lebanon. You can take the time offset into consideration by using the daylightSavingTimeOffset(for:) method on your time zone:
func UTCToLocal() -> String {
let a = "2:36:27 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm:ss aa"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: a)
dateFormatter.timeZone = TimeZone.current
let offset = dateFormatter.timeZone.daylightSavingTimeOffset(for: dt!)
dateFormatter.defaultDate = Date()
dateFormatter.dateFormat = "hh:mm:ss aa"
return dateFormatter.string(from: dt! + offset)
}
UTCToLocal()
Note that dt is "Jan 1, 2000 at 2:36 PM" since you haven't specified the .day, .month, and .year date components in a

Date from String is not giving correct date

I want to set "EST" as the default time zone for every user, but there is one condition that needs to be check in the current date at 7:45 PM. So I am comparing two dates, but the problem is when I convert the current Date to String it gives me the correct EST time, when I convert that String again to Date in EST it gives me time 4 hours ahead of EST. Here is the code for conversion
class func getCurrentDateTime() -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
let dateString = dateFormatter.string(from: Date())
print(dateString)
let convertDateFormatter = DateFormatter()
convertDateFormatter.dateFormat = "dd-MM-yyyy"
convertDateFormatter.timeZone = TimeZone(abbreviation: "EST")
let currentDate = convertDateFormatter.string(from: Date())
print(currentDate)
let comparedDateFormatter = DateFormatter()
comparedDateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
comparedDateFormatter.timeZone = TimeZone(abbreviation: "EST")
let comparedDate = comparedDateFormatter.date(from: "\(currentDate) 19:45:00")
print(comparedDate)
let currentDateFormatter = DateFormatter()
currentDateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
comparedDateFormatter.timeZone = TimeZone.init(abbreviation: "EST")
let currentDateAndTime = currentDateFormatter.date(from: dateString)
print(currentDateAndTime)
return dateString
}
So a date does not have a time zone.
So when I use a dateFormatter to convert a date to a string representation of the string will reflect the time zone the dateFormatter is set to.
But when you use the same formatter to convert the the string back into a date the date would not have the the time zone offset anymore.
So this sounds to me as if it is working properly.
Edit:
So if you are trying to compare two dates I would do something like:
let date1 = Date()
let date2 = Date().addingTimeInterval(100)
if date1 == date2 {
// dates are exactly equal
} else if date1 > date2 {
// date1 is the most recent
} else if date1 < date2 {
// date2 is the most recent
}
And if I were trying to display these dates I would use the date formatter to convert them to strings.
I modified the code as you requested:
func getCurrentDateTime() -> String {
var checkString : String!
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss a"
let dateString:String! = dateFormatter.string(from: Date())
let dateFormatter1 = DateFormatter()
dateFormatter1.timeZone = TimeZone(abbreviation: "EST")
dateFormatter1.dateFormat = "dd-MM-yyyy HH:mm:ss"
let dateString1:String! = dateFormatter1.string(from: Date())
let convertDateFormatter = DateFormatter()
convertDateFormatter.dateFormat = "dd-MM-yyyy"
convertDateFormatter.timeZone = TimeZone(abbreviation: "EST")
let currentDateformat = convertDateFormatter.string(from: Date())
let compareDate = "\(currentDateformat) 07:45:00 PM"
let compareDate1 = "\(currentDateformat) 07:45:00"
if dateString == compareDate {
checkString = "equal date"
}
if dateString1 < compareDate1{
checkString = "greater than"
} else {
checkString = "less than"
}
return checkString
}
func getCurrentDateTime() -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
let dateString = dateFormatter.string(from: Date())
let convertDateFormatter = DateFormatter()
convertDateFormatter.dateFormat = "dd-MM-yyyy"
convertDateFormatter.timeZone = TimeZone(abbreviation: "EST")
let currentDate = convertDateFormatter.string(from: Date())
let comparedDateFormatter = DateFormatter()
comparedDateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
let comparedDate = comparedDateFormatter.date(from: "\(currentDate) 19:45:00")
let currentDateFormatter = DateFormatter()
currentDateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
let currentDateAndTime = currentDateFormatter.date(from: dateString)
return dateString
}
Plesae check this code .
Actually I didn't find anything wrong with the code.
The Date always be in UTC timezone. The DateFormatter did the magic.
To print Date in as per the format:
use string(from:) method.
if let currentDateAndTime = currentDateFormatter.date(from: dateString) {
print(currentDateFormatter.string(from: currentDateAndTime))
}
NB: When working with fixed format dates, such as RFC 3339, you set
the dateFormat property to specify a format string. For most fixed
formats, you should also set the locale property to a POSIX locale
("en_US_POSIX"), and set the timeZone property to UTC.

Ios Swift Date Convert from TimeZone

dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "KST")
let nowstring = dateFormatter.string(from: Date())
let nowdate = dateFormatter.date(from: nowstring)
print(nowstring)
print(nowdate)
print this 2018-07-24T15:06:26
Optional(2018-07-24 06:06:26 +0000)
i want nowdate value 2018-07-24T15:06:26
but String to Date without timezone
I have to use to timeIntervalSince so nowdate is must have timezone
let today = NSDate()
print("\(today)")
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let nowDatestring = formatter.string(from: today)
formatter.timeZone = TimeZone(abbreviation: "KST")
let kstDate = formatter.date(from: nowDatestring)
print("\(kstDate!)")
formatter.timeZone = TimeZone(abbreviation: "PST")
let pstDate = formatter.date(from: nowDatestring)
print("\(pstDate!)")
formatter.timeZone = TimeZone(abbreviation: "IST")
let istDate = formatter.date(from: nowDatestring)
print("\(istDate!)")
Date is a specific point in time, which is independent of time zone. If you print a date value it will be always independent of any calendar or time zone. It will give same value for you(KST) and me(IST). You can specify your time zone when you format it using DateFormatter.

Resources