Convert any time to GMT +3 in Swift - swift

I would like to convert any time, UTC,, GMT+2 .. etc , anything to be only GMT +3
I tried this code but no success
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
formatter.timeZone = TimeZone.current
let currentdate = formatter.string(from: date)
print("currentdate \(currentdate)")
let gmt = DateFormatter()
gmt.timeZone = TimeZone(secondsFromGMT: 3600*3)
gmt.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let gmtDate = gmt.date(from: currentdate)!
print("gmtDate -> \(gmtDate)")
I tried abbreviations for the time zone, same result the date comes out to be only GMT.
Any ideas?

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 Date to a String. 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.

Swift 5
private func convertDate(string:String) -> String {
let dateFormatter = DateFormatter()
// format in which the date and time comes from the server
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
// set the time zone, the time is stored on the server
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3")
// convert to Date
let date = dateFormatter.date(from: string)
// now set our local time zone
dateFormatter.timeZone = TimeZone.current
// time format we need
dateFormatter.dateFormat = "dd.MM.yyyy HH:mm"
// convert the Date obtained above into text format
let displayString = dateFormatter.string(from: date!)
// local time is ready)))
return displayString
}

Related

How to parse date in "2022-03-04T10:30:00-08:00" format correctly in swift?

I have date coming from API shown below. These dates are for different countries.
dateTime = "2022-03-04T14:30:00-08:00"
I need to convert this use it both as Date and as String. But I do not know if date and time I am converting are correct. I am using following code:
To Convert String from API to Date:
extension String {
var CommonDateFormat: Date? {
get {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return dateFormatter.date(from: self)
}
}
}
To Convert Date to String:
extension Date {
func getDateAccoringTo(format: DateFormat ) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format.rawValue
dateFormatter.timeZone = .current
dateFormatter.timeZone = TimeZone.init(identifier: "UTC")
return dateFormatter.string(from: self)
}
}
enum DateFormat: String {
case ddmmyyyy = "dd/MM/yyyy"
case mmddyyyy = "MM/dd/yyyy"
case mmmd_yyyy = "MMM d, yyyy"
case llll_yyyy = "LLLL ,yyyy"
case TIME = "HH:mm:ss"
case day = "dd"
}
When I try to get day from date it always gives next day date. For example if date = "2022-03-04T14:30:00-08:00" then if I try to get day using code below
date?.getDateAccoringTo(format: .day)
This returns 5 not 4
date?.getDateAccoringTo(format: .TIME)
This returns time 00:00:00
Am I missing something important which is leading to these values?
Also, if I am missing something in my question kindly let me know so that I can improve it.
The given string
let dateTime = "2022-03-04T14:30:00-08:00"`
is a standard ISO8601 formatted date string. It can be converted to Date with
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: dateTime)!
At this specific point in time it is
14:30 on Friday, March 4 in Denver, CO, USA
22:30 on Friday, March 4 in London, UK
06:30 on Saturday, March 5 in Tokyo, Japan
Now let's see how Xcode displays dates.
print displays Date instances always in UTC indicated by +0000 which is the London time zone unless you print(date.description(with: .current), this displays the date in the local time zone.
In a Xcode Playground the result area displays Date instances in the local time zone except in print lines.
Last point to consider is that DateFormatter converts Date to String in the local time zone if no time zone is specified.
Keeping this behavior in mind you get the next day if you convert the date to string with DateFormatter but without specifying the time zone and your local time zone is greater than or equal to +01:30.
And you get the time 00:00 if you convert the date to string with DateFormatter but without specifying the time zone and your local time zone is exactly +01:30 which is a pretty unusual time zone by the way.

Swift 5 Datetime Conversion triple timezone cast (???)

I have a DateTime that I'm reading from an API that is in GMT.
I want to force cast it to an EST date object.
The original object is a string that I then cast to a Date to do some time comparison. Unfortunately, I don't think I did this right which made me do this unholy abomination:
extension String {
//this force casts from our original data being in GMT to EST
func getDateTimeTZ() -> Date{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
if let date = dateFormatter.date(from: self) {
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
let localTime = dateFormatter.string(from: date)
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
return dateFormatter.date(from: localTime)!
}
return dateFormatter.date(from: self)!
}
}
For whatever reason, I seem to have to flip the dateformatter 3 times to get the correct EST string output. Is there a better way to do this?
A Date is not associated with a time zone. From the Date reference:
A specific point in time, independent of any calendar or time zone.
...
A Date value encapsulate a single point in time, independent of any particular calendrical system or time zone. Date values represent a time interval relative to an absolute reference date.
So there is no such thing as “an EST date object” in the iOS SDK.
Time zones are relevant when converting to or from strings and when manipulating the calendrical components (year, month, day, hour, minute, second, etc.) of a Date.
The code you posted computes a new Date that is offset from the original date by the time offset between GMT and EST, but the new Date is not “an EST date object”.
(Incidentally, "EST" means Eastern Standard Time, and will not switch to daylight saving time during the appropriate part of the year. Use "US/Eastern" to get the appropriate time conversion depending on the day of year.)
You say you're doing this adjustment “to do some time comparison”, but you don't say what you're comparing to. It would help for you to describe what comparison you're performing.
For example, let's you want to check whether the Date is in the range 8:30 AM to 3:00 PM in the US/Eastern time zone, regardless of the day. If the input string is GMT, then you should parse it that way, as you do in your code:
let parser = DateFormatter()
parser.timeZone = TimeZone.init(identifier: "GMT")
parser.dateFormat = "yyyy-MM-dd HH:mm"
let date = parser.date(from: "2021-03-26 19:55")!
Then, use a Calendar set to the "US/Eastern" TimeZone to compute the hour and minute components of the Date:
var calendar = Calendar.current
calendar.timeZone = TimeZone(identifier: "US/Eastern")!
let components = calendar.dateComponents([.hour, .minute], from: date)
let hhmm = components.hour! * 100 + components.minute!
if (08_30 ..< 15_00).contains(hhmm) {
print("school time")
} else {
print("play time")
}

How can I convert GMT date to system date format?

I have a Date : 2019-07-18 00:30:32 GMT+10:00.
I want to convert string to date but its gives wrong date.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ"
dateFormatter.timeZone = NSTimeZone.local;
dateFormatter.locale = NSLocale.current;
let date = dateFormatter.date(from:isoDate)!
Its gives wrong date : "Jul 17, 2019 at 8:00 PM"
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.
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
Reference : Apple
I seen it shows correct date, It is based on your Time zone:
Check with :
https://www.epochconverter.com/

Time stamp from string issue?

I have two string , date and time . date string has a date in format "MM-dd-yyyy" and time in format "hh:mm a" , I want to create a 10 digit timestamp from the same . I did the following but I am getting issue with this. Any help is appreciated.
let idate = (userInstance.userData?.Date!)! + "T" + (userInstance.userData?.Time!)! + "+0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: idate)!
print(date)
let timestamp = Int(date.timeIntervalSince1970)
print(timestamp)
You cannot force a date containing AM/PM time to ISO 8601. ISO 8601 dates are always represented in 24-hour mode.
Besides your order of year, month and day is not ISO 8601 compliant.
Specify the appropriate date format MM-dd-yyyyhh:mm aZ
let datePart = "09-18-2018"
let timePart = "4:22 pm"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM-dd-yyyyhh:mm aZ"
let date = dateFormatter.date(from: datePart + timePart + "+0000")!
let timestamp = Int(date.timeIntervalSince1970)
print(timestamp)
You are crashing here:
let date = dateFormatter.date(from: idate)!
That's because you are claiming that idate is a string in this format:
"yyyy-MM-dd'T'HH:mm:ssZ"
But it isn't. When you convert from a string to a date, your format string must exactly match the format of the string.
Then you can supply a different format and convert the date to a new string.

Convert date string of one time zone to date object in local time Swift

I want dateString in this format "2016-12-22T08:00:00-08:00" to be converted to date object in users local time for example 2016-12-22 21:30:00 +0530 when the users time is +05:30 from UTC
OR
I want dateString in this format "2016-12-22T08:00" which is PST time to be converted to date object in users local time for example 2016-12-22 21:30:00 +0530 when the users time is +05:30 from UTC or 2016-12-22 16:00:00 +0000 when the users time is 00:00 from UTC
When I try the below code and print dateObject it prints Optional(2016-12-22 02:30:00 +0000) but I want 2016-12-22 21:30:00 +0530 since my local time is +05:30 from UTC.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss-08:00"
dateFormatter.timeZone = NSTimeZone.local
let dateString = "2016-12-22T08:00:00-08:00"
let dateObject = dateFormatter.date(from: dateString)
print("dateObject \(dateObject1)")
Fix your dateFormat to:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
Remove the timeZone line. It's not needed since your date string specifies its own timezone.
dateFormatter.timeZone = NSTimeZone.local // remove this line
Now your code works fine.
"But wait, the output of print(dataObject) isn't what I want"
Yes it is. Like thousands before you, you misunderstand the output of printing a Date object.
If you wish to view a Date in the local timezone, in a given format, use a DateFormatter to convert the Date into a String. You will get the current, local timezone by default.
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long
let newString = dateFormatter.string(from: dateObject)
print(newString)
And you get just what you wanted.