Not able to convert UTC time - ios

I'm getting this UTC time in string format from the server.."2019-12-18T10:58:40Z"
Now I want to convert it into local time. For that I referred this link. But it's not working..
What I wanted to achieve was to convert UTC time to local time and set a timer based on that time.
This is what I've tried..
var utcTime = "\(json["expirationDate"]!)"
self.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let date = self.dateFormatter.date(from: utcTime)
let utcDate = date?.toGlobalTime()
let localDate = utcDate?.toLocalTime()
But I'm getting nil values for the dates..

You don't have milliseconds in your UTC date string example. Your date format should be
self.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"

you have to change this format from
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" to "yyyy-MM-dd'T'HH:mm:ss'Z'"**you have to
let utcTime = "2019-12-18T10:58:40Z"
let dateFormatter = DateFormatter.init()
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")!
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
let date = dateFormatter.date(from: utcTime)
print(date)

Related

Wrong date in swift 5 after conversion [duplicate]

This question already has answers here:
How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift?
(13 answers)
Closed 3 years ago.
I am converting current date into GMT/UTC date string. But every time it returns me with wrong date.
My todays date is 07 February 2020, 11:09:20 AM. You can refer below image.
Here is my code :
let apiFormatter = DateFormatter()
//apiFormatter.dateStyle = DateFormatter.Style.long
//apiFormatter.timeStyle = DateFormatter.Style.long
//apiFormatter.calendar = Calendar.current
apiFormatter.timeZone = TimeZone.init(identifier: "GMT") //TimeZone(abbreviation: "UTC") //TimeZone.current //
//apiFormatter.locale = Locale.current
//apiFormatter.dateFormat = "yyyy-MM-DD HH:mm:ss"
apiFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
//apiFormatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ssZ"
let endDate = apiFormatter.string(from: Date())
print(endDate)
And what I am getting in return is also you can check in image - 2020-02-38T05:33:34.598Z. I have tried with all the format, but no any luck. Can anyone suggest where it is going wrong?
First of all, the format should be:
apiFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
The Z is not a literal letter, it's the description of the time zone. However, making it a literal won't probably make a problem.
The 38 for day from your output is obviously caused by the DD format you have commented out.
Nevertheless, you have to set the locale:
apiFormatter.locale = Locale(identifier: "en_US_POSIX")
Otherwise you will have problems with 12/24h switching.
let apiFormatter = DateFormatter()
apiFormatter.locale = Locale(identifier: "en_US_POSIX")
// remove this if you want to keep your current timezone (shouldn't really matter, the time is the same)
apiFormatter.timeZone = TimeZone(secondsFromGMT: 0)
apiFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let endDate = apiFormatter.string(from: Date())
print(endDate) // 2020-02-07T08:25:23.470+0000
print(Date()) // 2020-02-07 08:25:23 +0000
Also note that you can use ISO8601DateFormatter instead of DateFormatter.
Try this and adjust according to what format you are getting from server -
private func getFormatedDateInString(_ dateString: String) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
if let date = dateFormatter.date(from: dateString) {
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.timeZone = TimeZone.current
let timeStamp = dateFormatter.string(from: date)
return timeStamp
}
return nil
}

dateFormatter returns wrong date with two digit year specifier [duplicate]

For date Input "00/02/02"
formating Style is yy/MM/dd
I am getting correct output like 02/01/2000
But issue is when trying with "00/01/01"
getting output like this '01/01/12100'
But I don't know why this year coming like 12100
My code is
let str = "00/01/01"
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yy/MM/dd"
if let showDate = inputFormatter.date(from: str) {
inputFormatter.dateFormat = "dd/MM/yyyy"
let resultString = inputFormatter.string(from: showDate)
print(resultString)
}
year input type always as yy format.
As per the #MartinR suggestion
settinginputFormatter.defaultDate to current date or Date(timeIntervalSinceReferenceDate: 0) its worked fine
let str = "00/01/01"
let inputFormatter = DateFormatter()
inputFormatter.defaultDate = Date(timeIntervalSinceReferenceDate: 0)
inputFormatter.dateFormat = "yy/MM/dd"
if let showDate = inputFormatter.date(from: str) {
inputFormatter.dateFormat = "dd/MM/yyyy"
let resultString = inputFormatter.string(from: showDate)
print(resultString)
}
I managed to reproduce this bug by setting the timezone of the formatter, before getting the date from it, to your local timezone:
inputFormatter.timeZone = TimeZone(identifier: "Asia/Kolkata")
//Or
inputFormatter.timeZone = TimeZone(identifier: "Asia/Calcutta")
They both lead to 01/01/12100.
Actually, using a date format of yy/MM/dd hh:mm:ss, all dates starting from 00/01/01 00:00:00 to 00/01/01 05:29:59 give a year component of 12100. This is due to the time zone of Kolkata being offset by +05H30 from GMT. This is a bug.
Setting the timezone to UTC yields the desired output:
inputFormatter.timeZone = TimeZone(identifier: "UTC") //01/01/2000
This bug occurs with other timezones too:
inputFormatter.timeZone = TimeZone(identifier: "Africa/Addis_Ababa")
inputFormatter.timeZone = TimeZone(identifier: "Europe/Moscow")
inputFormatter.timeZone = TimeZone(identifier: "Asia/Hong_Kong")
Basically all timezones that have GMT + hh:mm

How to change the timeZone in SwiftDate?

I have displayed the list of timezones in my app. If user selects a particular timezones, I need to change the local timezone to the selected timezone by the user.
let region = Region(tz: timeZoneName.timeZone , cal: cal, loc: cal.locale!)
let date = Date().inRegion(region: region).absoluteDate
Here is the problem, the region is changed to the selected timezone but the date issuing the local timezone.
A Date contains no timezone. From apple's docs: A specific point in time, independent of any calendar or time zone.
The timezone comes into play as soon as you want to present a date to the user. And that's what a DateFormatter is for. As #AlexWoe89 already pointed out, it let's you convert a string, containing a date into a Date object, but also lets you convert a given date into a string representing the date in the time zone you set to the timeZone property of DateFormatter.
let date = Date()
var dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
dateFormatter.timeZone = TimeZone(identifier: "America/Los_Angeles")
let dateString1 = dateFormatter.string(from: date)
dateFormatter.timeZone = TimeZone(identifier: "Germany/Berlin")
let dateString2 = dateFormatter.string(from: date)
This will store 2017-10-23 04:27 in dateString1, while the same date leads to 2017-10-23 13:27 in dateString2.
You can use DateFormatter as a solution, try something like this:
let dateString = "<yourDateAsString>"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // => there are a lot of identifiers you can use
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.defaultDate = Date()
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm” // => your needed time format
let convertedDate = dateFormatter.date(from: dateString)

Converting string EST time to localized time

Assume I'm given an input string like "7:00". I know that the time is EST but I want to convert it to localized time (so for people in PST it says 4:00). I tried the following code, but I keep getting a 24-hour time from it and the complete date (e.g: Optional(2000-01-01 16:00:00 +0000)). I want just the hour:min time...what am I doing wrong?
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
gameClock = "\(dateFormatter.dateFromString("7:30"))"
println(gameClock)
You need to specify the time zone for your date formatter that you use to process the server date. By default, the time zone of the date formatter is the default time zone of the device.
So, for your above code, you should do this:
let dateStringFromServer = "07:00"
let serverDateFormatter = NSDateFormatter()
serverDateFormatter.dateFormat = "HH:mm"
serverDateFormatter.timeZone = NSTimeZone(name: "EST")
let dateFromServer = serverDateFormatter.dateFromString(dateStringFromServer)
let localDateFormatter = NSDateFormatter()
serverDateFormatter.dateFormat = "HH:mm"
let localizedStringForThatDate = localDateFormatter.stringFromDate(dateFromServer!)
The dateFormatter.dateFromString("7:30") gives you an NSDate not an NSString. You have make use of another NSDateFormatter object to get the date in desired string format.
let dateFormatterForDisplay = NSDateFormatter();
dateFormatterForDisplay.dateFormat = "HH:mm"
dateFormatterForDisplay.locale = NSLocale(localeIdentifier: "en_US_POSIX")
(you need the last line in the above if you want to force 12 hour mode, the default is NSLocale.currentLocale() and can be 12 hr or 24 hr mode for different locales)
Then
let displayString = dateFormatterForDisplay.stringFromDate(gameClock)

How to display date with human language like "Today at xx:xx pm", "Yesterday at xx:xx am"?

I have a date "2014-07-02 20:57:38 +0000" and I want to format it as "Today at 8:57 pm".
I want that if a string is yesterday, then display it as "Yesterday at 9:00 am". If it is neither today or yesterday, just show the actually date like "27/6 at 7:53 pm".
I was able to get the time with format like "8:57 AM" with the code below.
var formatter : NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "h:mm a"
// message.createdAt is the date
let dateString = formatter.stringFromDate(message.createdAt)
println(dateString)
//output = 8:57 AM
However, when I use the following code, it returns a blank string.
var formatter : NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "h:mm a"
formatter.doesRelativeDateFormatting = true //<-- This doesn't work
let dateString = formatter.stringFromDate(message.createdAt)
println(dateString)
//output = (nothing, its a blank string)
How do I make this work and display "Today" or "Yesterday" in Swift?
The reason it's blank is that your date format only has time components. Combined with .doesRelativeDateFormatting that gives you the empty string. If you want that custom time format, I think you need separate formatters for the date and the time:
let now = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.doesRelativeDateFormatting = true
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "h:mm a"
let time = "\(dateFormatter.stringFromDate(now)), \(timeFormatter.stringFromDate(now))"
println(time) // prints "Today, 5:10 PM"
With Swift 5.1, Apple Developer API Reference states about DateFormatter's dateFormat property:
You should only set this property when working with fixed format representations, as discussed in Working With Fixed Format Date Representations. For user-visible representations, you should use the dateStyle and timeStyle properties, or the setLocalizedDateFormatFromTemplate(_:) method if your desired format cannot be achieved using the predefined styles; both of these properties and this method provide a localized date representation appropriate for display to the user.
The following Playground sample code shows how to display your dates in the desired format using dateStyle, timeStyle and doesRelativeDateFormatting properties:
import Foundation
let now = Date() // 2019-08-09 12:25:12 +0000
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: now)! // 2019-08-08 12:25:12 +0000
let aWeekAgo = Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: now)! // 2019-08-02 12:25:12 +0000
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true
let nowString = dateFormatter.string(from: now)
print(nowString) // prints: Today at 2:25 PM
let yesterdayString = dateFormatter.string(from: yesterday)
print(yesterdayString) // prints: Yesterday at 2:25 PM
let aWeekAgoString = dateFormatter.string(from: aWeekAgo)
print(aWeekAgoString) // prints: August 2, 2019 at 2:25 PM
Give this a try in Swift:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true
let date = Date()
let dateString = dateFormatter.string(from:date)

Resources