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
Related
func getDateWithoutTimeForDisplay() -> String {
let formatter = DateFormatter()
// formatter.locale = Locale(identifier: "en_US")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.locale = Locale(identifier: "en_US_POSIX")
let myStringafd = formatter.date(from: self)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
dateFormatter.timeZone = NSTimeZone.local
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
if let myStringafd = myStringafd {
let somedateString = dateFormatter.string(from: myStringafd)
return somedateString
}
return ""
}
this is my code to convert given UTC date to system date based on the local time zone.
The actual problem is, suppose the case "i have the time 1.00 AM on the date 25-08-2020, according to the Indian time zone, ( UTC time is 5.30 lesser than Indian time) the corresponding UTC date is 24-08-2020 due to the time difference with the Indian time". In this case i want to convert the UTC date(Because it is effecting the date to be display for the user) to the current system date.
My system date&time is 25-08-2020 1:00 AM (Indian time)
the corresponding UTC date is 24-08-2020. -5:30 hr
i need to convert the UTC date to the current local time
Try this out:
let currentDate = self.UTCToLocal(date: Date().description) //This will pass system date in UTC format to the function and function will return desired output in local timezone
func UTCToLocal(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ssz" //The date format should be exact as same as UTC date
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = NSTimeZone.local
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss" //The desired date format in which you may want to return the value
return dateFormatter.string(from: dt!)
}
or you can check this post - Returning nil when converting string to date in swift and this link for dateFormatters - https://nsdateformatter.com/
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)")
}
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.
I'm using a standard DatePicker and printing the date on top of it.
For some reason my Date Picker has it's timezone set to IST, which maybe because of the locale.
Let's get into an example:
DatePicker -> 12:00 PM Date reads -> 06:30:00 +0000
Which is correct as the date will print UTC time and IST is UTC+5:30
Now when I change the timezone of the DatePicker, let's say to London which is GMT+1,
DatePicker -> 12:00 PM Date reads -> 06:30:00 +0000
Where in the date should actually read 11:00:00
How I am changing the DatePicker's timezone:
if let tmz = selectTimeZone {
datePicker.timeZone = tmz
}
i have the same issue sometime before but for the another reason. Try this hope it will help.
First -
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
var startDate = dateFormatter.string(from: yourdatepicker.date)
startDate = localToUTC(date: startDate)
Second we convert this to local to UTC , here we mention the TimeZone to system time
func localToUTC(date:String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = NSTimeZone.system
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dt = dateFormatter.date(from: date)
return dateFormatter.string(from: dt!)
}
Third if you want to conver UTC to your Local time
func UTCToLocal(date:String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = NSTimeZone.system
dateFormatter.dateFormat = "hh:mm a"
return dateFormatter.string(from: dt!)
}
I know there are lot of questions passing around over this simple issue, but still I couldn't get a clear idea.
Here is what I want:
SelectedDateString = "19-08-2015 09:00 AM"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm a"
dateFormatter.timeZone = NSTimeZone();
let SelectedUTCDate = dateFormatter.dateFromString(SelectedDateString)!
println("SelectedLocalDate = \(SelectedLocalDate)")
// OUTPUT: SelectedLocalDate = 2015-08-18 18:30:00 +0000
If I dont use TimeZone:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm a"
// dateFormatter.timeZone = NSTimeZone();
let SelectedUTCDate = dateFormatter.dateFromString(SelectedDateString)!
println("SelectedLocalDate = \(SelectedLocalDate)")
//OUTPUT: SelectedLocalDate = 2015-08-18 19:26:00 +0000
Why is there change in the time and Date? What I want is:
//OUTPUT: SelectedLocalDate = 2015-08-19 09:00:00 +0000
Also I want to convert the Local Date to Exact UTC Date
//Like this: SelectedUTCDate = 2015-08-19 03:30:00
inputString = "19-08-2015 10:45 am" // My localtime is 10:35 AM, so I set 10 mins from now
var currentUTCTime = NSDate() // currentUTCTime is 05: 15 AM.
I want to convert the inputString to its respective UTC Time and find the difference between the two times in both date and string.
//Like this Date: diffInDate: 00-00-0000 00:10 and
// Like this String: diffInString: 10 mins
How can I get both of these?
let dateString = "19-08-2015 09:00 AM"
let dateFormatter = DateFormatter()
dateFormatter.calendar = Calendar(identifier: .iso8601)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm a"
if let dateFromString = dateFormatter.date(from: dateString) {
print(dateFromString) // "2015-08-19 09:00:00 +0000"
dateFormatter.timeZone = .current
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm a Z"
dateFormatter.string(from: dateFromString) // 19-08-2015 06:00 AM -0300"
}
extension Date {
func originToString(dateFormat: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.calendar = Calendar(identifier: .iso8601)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return dateFormatter.string(from: self)
}
}