UTC to local time conversion not working in Swift 2 - swift

I am trying to convert a UTC time to local timezone, but it doesn't seem to be converting it at all:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date1 = dateFormatter.dateFromString(dateStringFromServer)!
dateFormatter.timeZone = NSTimeZone.localTimeZone()
let date2 = dateFormatter.dateFromString(dateStringFromServer)!
The dateStringFromServer is a string representation of a UTC date. So I was expecting date1 to be in UTC, and date2 to be in PDT (my local time zone), but they are both the same. Something wrong with my syntax?
This is what I'm getting:
dateStringFromServer: 2016-10-21T05:24:26.000Z
date1: 2016-10-21 05:24:26 +0000
date2: 2016-10-21 05:24:26 +0000
How can I get date2 be in the device's local timezone?

If you want to convert to the time zone set on the device you can do this
Swift3
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date1 = dateFormatter.date(from: dateStringFromServer)
// return the timeZone of your device i.e. America/Los_angeles
let timeZone = TimeZone.autoupdatingCurrent.identifier as String
dateFormatter.timeZone = TimeZone(identifier: timeZone)
let date2 = dateFormatter.string(from: date1)
Swift2
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date1 = dateFormatter.dateFromString(dateStringFromServer)
// return the timeZone of your device i.e. America/Los_angeles
let timeZone = NSTimeZone.localTimeZone().name
dateFormatter.timeZone = NSTimeZone(name: timeZone)
let date2 = dateFormatter.stringFromDate(date1!)

It's the same because even though you think you're setting the date formatter's time zone to the current time zone after setting the first date, it doesn't matter. If you don't set the date formatter's time zone, it automatically sets to the system time zone as specified in Apple's docs for NSDateFormatter:
If unspecified, the system time zone is used.
Therefore the date formatter's time zone is set to be the same both implicitly for the first date and explicitly for the second date because they happen to be identical, hence you're getting the same date back.

Here is the code that work in swift4.
func UTCToLocal(date:String, fromFormat: String, toFormat: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = fromFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = toFormat
return dateFormatter.string(from: dt!)
}
How to use :-
let localDateAsString = UTCToLocal(date: deadline!, fromFormat: "yyyy-MM-dd HH:mm:ss", toFormat: "MM-dd-yyyy hh:mm a")

Related

From UTC to local time doesn't consider daylight saving swift

I am using this function to convert UTC time to my local time stamp.
func UTCToLocal(date:String, timeZone: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "H:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = TimeZone(identifier: timeZone)
dateFormatter.dateFormat = "h:mm a"
return dateFormatter.string(from: time)
}
But this doesn't check DST. So, I am getting one hour difference. Can anyone help me with some general solution for this problem?
Thanks to Leo who have figured out the issue. I have updated the functions as:
func UTCToLocal(date:String, timeZone: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = TimeZone(identifier: timeZone)
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm aa"
return dateFormatter.string(from: dt!)
}
Now the date string in function paramter have value in this format "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'". This solves the issue.
The issue here is the lack of the date. You are always passing only the time components without the day so the daylight savings time Will always be correspondent to January 1st 2001. If you need today’s date you need to set the date formatter defaultDate property to the startOfDay for today. Btw don’t forget to set the locale first to “en_US_POSIX” before setting the fixed date format.

How to convert UTC string to local date in swift?

I have following UTC like 2020-07-15T12:32:38+00:00. I actually need to convert this string to local date in phone taking into account a timezone. Here is my try that I see from other stackoverflow answers:
func UTCToLocal(date: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
//I thought than below can help
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
return dateFormatter.date(from: date)
}
Another approach:
func UTCToLocal2(date: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
/// I thought that specifying current time zone would help
dateFormatter.timeZone = TimeZone.current
return dateFormatter.date(from: date)
}
But none of approach works. My 2020-07-15T12:32:38+00:00 is not converted to date with my timezone. Where is my mistake?

Convert UTC DateTime to local datetime does not show correctly in swift

I am using swift 4. I need to convert my UTC Time to local time.But it shows two hour before. I am now Living in dhaka with GMT+6. Here is code i used ..
var date:String = "2020-02-10 14:30:57 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss a"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "yyyy-MM-dd h:mm a"
let convertedLocalTime = dateFormatter.string(from: dt!)
tv_time.text = convertedLocalTime
print("convertedLocalTime-->",convertedLocalTime)
It shows 2020-02-10 6:30 PM But now 8.30 PM . What is the wrong with the code
Please help me
Your input data is not correctly formatted.
If you can use a correct format for the input data:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
// set the date in UTC
let date = dateFormatter.date(from: "2020-02-10 14:30:57")
dateFormatter.timeZone = TimeZone.current
// String representation of the date for local time
let s = dateFormatter.string(from: date!)
this snippet sets s to "2020-02-10 15:30:57" which is correct for Germany.
Otherwise you have to correct the format of your input data, e.g. delete the "PM" from the 24h format string.

How can I determine the time zone of a given (local) date

From an API I get the following two date strings. Those dates show the time of a weather observation of a weather station that’s located in some time zone.
dateUTC = "2019-06-14T18:00:00Z"
dateLocal = "2019-06-14 20:00:00"
How can I determine the time zone the weather station is in?
(Not the time zone of the user!)
I've tried to use the DateFormatter, but unfortunately the local date gets immediately transformed to GMT - and it's then identical with the UTC date.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let dateUTC = dateFormatter.date(from: current.currentObservation[0].timeUTC)!
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateLocal = dateFormatter.date(from: current.currentObservation[0].timeLocal)!
I would like to see as the result of the above date(s):
Time zone = GMT+2
The answer was quite simple - still I didn't see it for hours. The trick is to set a timeZone for the DateFormatter.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let dateUTC = dateFormatter.date(from: current.currentObservation[0].timeUTC)!
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dateLocal = dateFormatter.date(from: current.currentObservation[0].timeLocal)!
let difference = Calendar.current.dateComponents([.second], from: dateUTC, to: dateLocal).second!

Swift 3.0 Converting String to Date

I'm trying to convert String date to local timeZone date then convert it back to Date with my current timeZone first method is working well:
let date = convertToLocalTimeZone(dateStr:"2018-05-30T14:13:20.000Z")
print(date)
the following is printed which is right:
2018-05-30 16:13GMT+2
let newDate = convertStringToDate(dateStr:date)
print(newDate)
//Converted back to UTC Time Zone :(
2018-05-30 14:13:00 +0000
func convertToLocalTimeZone(dateStr:String)->String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:sss.SSSZ"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date = dateFormatter.date (from: dateStr)
dateFormatter.timeZone = TimeZone(secondsFromGMT: getSecondsFromGMT())
dateFormatter.dateFormat = "yyyy-MM-dd HH:mmz"
let strVal = dateFormatter.string(from: date!)
return strVal
}
The problem happens when i try to convert the new String date with my local timeZone to date it returns wrong timeZone:
func convertStringToDate(dateStr:String)->Date{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mmz"
// dateFormatter.timeZone = TimeZone(abbreviation: "GMT+2")
let date = dateFormatter.date (from: dateStr)
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour], from: date!)
let finalDate = calendar.date(from:components)
return finalDate!
}
Any Help will be much appreciated
I think your code is alright. You just have to understand that Date represents a point in time. It does not know anything about time zones. Time zones appears only when you format the date, so only in a String will you ever see a time zone. No matter how you create a Date, you are going to see it end up in UTC when it is printed directly.
So if you want to show a date in a time zone, format it, just like you did in convertToLocalTimeZone.
If you want, you could create your own date with a Date and a TimeZone:
struct ZonedDate: CustomStringConvertible {
var date: Date
var timeZone: TimeZone
var description: String {
// format the date using timeZone here...
}
}