Your code has a lot of issues. First, there is no reason to go from Date to String and back to Date. Second, if you are converting a String to a Date, and the String contains its own timezone information, then setting the formatter's timeZone is pointless. The timezone in the string will be used when calculating the associated Date. There are only two cases where setting a date formatter's timezone makes sense:
- When parsing a date/time string that does not contain any timezone information. The formatter's timezone will then be used to interpret the string.
- When converting a Dateto aString. The formatter's timezone will be used when generating the resulting string from the date.
If you simply want to show any Date as a String in a specific timezone then all you need is:
let date = Date() // some date
print("Original Date (in GMT): \(date)")
// Setup a formatter with a date and time style
let formatter = DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 3600 * 3) // the desired timezone
formatter.dateStyle = .long
formatter.timeStyle = .medium
let string = formatter.string(from: date)
print("GMT+3 style result: \(string)")
// For comparison, set the formatter to a specific format
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let string2 = formatter.string(from: date)
print("GMT+3 format result: \(string2)")
Output (for the en_US locale):
Original Date (in GMT): 2017-10-28 20:53:59 +0000
  GMT+3 style result: October 28, 2017 at 11:53:59 PM
  GMT+3 format result: 2017-10-28 23:53:59 +0300
There is no need to convert any time. Simply create a String from a Date to get the desired output.
Note that, by default, a DateFormatter shows its result in local time. Set the formatter's timeZone if you want the result in some other specific timezone.
Also note that printing a Date object always shows the date in UTC time (+0000). Many people get confused by this and think they are getting the wrong date when they are not.