I have two functions.
The first is writing NSDate() to NSUserDefaults as a string.
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"
let dateString = dateFormatter.stringFromDate(NSDate())
NSUserDefaults.standardUserDefaults().setObject(dateString, forKey: "lastDate")
NSUserDefaults.standardUserDefaults().synchronize()
The second one is reading this value, converting it to NSDate and comparing with the current time and date.
let dateString = try NSUserDefaults.standardUserDefaults().stringForKey("lastDate")
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"
if dateString != nil {
let date = try dateFormatter.dateFromString(dateString!)
if date != nil {
let interval = NSDate().timeIntervalSinceDate(date!)
let interval2 = Int(interval)
print(interval2)
}
} else {
//some code here
}
The thing is, it returns not 5 seconds (as it should, for example) but something like 43295 or 44592. I logged dates and strings and they seemed fine. Where did I break things?
Related
All,
I am trying to convert UTC date to local date . Below is my code. But, even after converting I get both dates in UTC only.
static func getTodayDateInLocalTimeZone() -> Date{
let todaydateInUTC = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let utcDateString = dateFormatter.string(from: todaydateInUTC)
print("Date::: utcDateString: \(utcDateString)")
// Changing to Current timezone
let timzoneIdentiier = TimeZone.current.identifier
let timezone = TimeZone(identifier: timzoneIdentiier)
let abbrv = timezone?.abbreviation()
let dateFormatter1 = DateFormatter()
dateFormatter1.timeZone = TimeZone(identifier: abbrv!)
dateFormatter1.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
print("Date:::timeZone: \(timzoneIdentiier) == \(String(describing: abbrv))")
let formattedDate1 = dateFormatter1.date(from: utcDateString)
print("Date:::: \(formattedDate1)")
return formattedDate1!
}
Here is what I get when I print
Date::: utcDateString: 2021-01-20T17:39:15+0000
Date:::timeZone: America/New_York == Optional("EST")
Date:::: Optional(2021-01-20 17:39:15 +0000)
Please let me know why is it now changing to the local timezone.
Thanks
First of all, a date does not have a time zone.
So let todaydateInUTC = Date() actually means let todaydate = Date().
The time zone becomes relevant, when you want to present a date to the user.
So instead of creating a new date from a the utcDateString, you just need to create another date string from the same date variable.
let formattedDate1 = dateFormatter1.date(from: utcDateString) becomes let tzDateString = dateFormatter1.string(from: todaydate).
This also means your function should return a string instead of a date.
For example:
func getTodayDateInLocalTimeZone() -> String
{
let now = Date()
// Just for debugging. Not for the result.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let utcDateString = dateFormatter.string(from: now)
print("Date::: utcDateString: \(utcDateString)")
let tz = TimeZone.current
let dateFormatter1 = DateFormatter()
dateFormatter1.timeZone = tz
dateFormatter1.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
print("Date:::timeZone: \(tz) == \(String(describing: tz.abbreviation()))")
let tzDateString = dateFormatter1.string(from: now)
print("Date:::: \(tzDateString)")
return tzDateString
}
For me it results in:
Date::: utcDateString: 2021-01-20T18:19:44+0000
Date:::timeZone: Europe/Berlin (current) == Optional("CET")
Date:::: 2021-01-20T19:19:44+0100
Trying to show the time and date separately in Swift 3 and both fields are returning nil. I'm receiving the date as a string thats in the standard Date() format.
public func formatDateForAbandonTicket(_ dte: String) -> String {
print(dte)
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HH:mm"
let t = timeFormatter.date(from: dte)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "d/MM/YYYY"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00")
let d = dateFormatter.date(from: dte)
print()
print(t)
print()
print(d)
return "\(d)" + " " + "\(t)"
}
I get a nil response from both d & t. The parameter does contain the right date "2017-11-14 16:36:29 +0000".
Thanks
Your code doesn't work because you need to first convert dte to a Date and to do that, you need to specify a format that matches the complete date string. You only need one Date, not two.
And there is no reason to create two separate strings just to combine them back into one.
public func formatDateForAbandonTicket(_ dte: String) -> String {
print(dte)
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
df.locale = Locale(identifier: "en_US_POSIX")
if let date = df.date(from: dte) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "d/MM/yyyy HH:mm"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let dateStr = dateFormatter.string(from: date)
return dateStr
} else {
return ""
}
}
Also note that you are converting the result to a time in UTC time instead of the user's locale time. That's fine if that is what you need, just make sure it makes sense to the user.
I am getting a particular string from the web service which is actually a time. So I want to check whether the string which i get from web service is in 24 hour format. I have successfully appended AM and Pm with this code:
let dateAsString = "13:15"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.date(from: dateAsString)
dateFormatter.dateFormat = "h:mm a"
let Date12 = dateFormatter.string(from: date!)
print("12 hour formatted Date:",Date12)
But i wish to know whether "13:15" is greater than "12:00" as this time i am getting from webservice.
Just pass the 12-hour date format and check for nil
let dateAsString = "13:15"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm"
let is24HourFormat = dateFormatter.date(from: dateAsString) == nil
What you did is just formatting date to nice readable string..
But what you actually looking for is comparing between dates:
See next example for comparing two dates [Swift 3.1]
func compareDates() {
let date1 = Date() // now
let date2 = Date().addingTimeInterval(20) // now+20secodns
switch date1.compare(date2) // return ComparisonResult
{
case .orderedAscending:
print("date1 < date2")
case .orderedDescending:
print("date1 > date2")
case .orderedSame:
print("date1 == date2")
}
}
And if you want to compare just times that you have already in 24h format and strings, you could just use normal comparison for strings but I don't recommend this
/// compare only times in 24h format in strings
func compareTimesInStrings() {
let time1 = "13:00"
let time2 = "09:05"
if time1 < time2 {
print("time1 < time2")
} else if time1 > time2 {
print("time1 > time2")
} else {
print("time1 == time2")
}
}
May be this is a long answer. But here is the another way :
let dateAsString = "13:15"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
if let date = dateFormatter.date(from: dateAsString) {
dateFormatter.dateFormat = "h:mm a"
let Date12 = dateFormatter.string(from: date)
let amRange = Date12.range(of: dateFormatter.amSymbol)
let pmRange = Date12.range(of: dateFormatter.pmSymbol)
if pmRange == nil {
print("12 hours")
} else if amRange == nil {
print("24 hours")
}
} else {
print("not in the time range") // if dateAsString is > 23:59
}
I am having trouble generating Date objects that match the json output. In http://chartapi.finance.yahoo.com/instrument/1.0/aapl/chartdata;type=quote;range=1y/json - the dates are in the following format "Date": 20151013. In order to get 2015-10-13, first I use Alamofire & SwiftJSON in my API call and JSON parsing. Here are some relevant lines from my code:
let dateInteger = subJson["Date"].int
if dateInteger != nil {
let editedDateInt = dateInteger!
let dateString = NSMutableString(string: "\(editedDateInt)")
dateString.insert("-", at: 4)
dateString.insert("-", at: 7)
chartpoint.date = Formatters.sharedInstance.dateFromString(key: dateString as String) }
// date extension
public class Formatters {
public static let sharedInstance = Formatters()
private let dateKeyFormatter = DateFormatter()
init() { dateKeyFormatter.dateFormat = "yyyy-MM-dd" }
public func dateFromString(key: String?) -> Date? {
guard let key = key else { return nil }
return dateKeyFormatter.date(from: key) }
Problem is the output came up Optional(2015-10-12 16:00:00 +0000). Not quite 2015-10-13 that I was expecting. How do I fix this? Is this related to user's Locale or TimeZone?
Check this out
Swift 3.0
let dateFromServer = "20151013"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
let date = dateFormatter.date(from: dateFromServer)
dateFormatter.dateFormat = "yyyy-MM-dd"
let finalDate = dateFormatter.string(from: date!)
print(finalDate)
Output:
2015-10-13
As suggested by #rmaddy changed the format style form YYYY to yyyy.
I tried from my end and browsed too. Might be this question have been asked many times. I parsed weather response of city's (ex: Mar del Plata) based on there timezone. I want time in HH:mm format. Below is the sample JSON response.
"sunrise": "2016-07-10T08:05:02-0300", "sunset": "2016-07-10T17:46:29-0300"
My code:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
guard let date = dateFormatter.dateFromString(dateString) else {
assert(false, "no date from string")
}
dateFormatter.dateFormat = "HH:mm"
//dateFormatter.timeZone = NSTimeZone(name: "UTC")
return dateFormatter.stringFromDate(date)
Whenever I print or display date string in label the hours is getting changed. I WANT exact time coming in response.
My temporary solution for the above is
// Begin - Its a temperory solution
if dateString.contains("T") {
print("dateString.contains(T)")
let myArray = dateString.componentsSeparatedByString("T")
if myArray.count > 0 {
let str = myArray[1]
if str.contains("+") {
print("(str.contains(+))")
let myArr = str.componentsSeparatedByString("+")
if myArr.count > 0 {
let str1 = myArr[0]
if str1.contains(":") {
print("str1.contains(:)")
let myAr = str1.componentsSeparatedByString(":")
if myAr.count > 0 {
let str2 = myAr[0]
let str3 = myAr[1]
let str4 = "\(str2):\(str3)"
print(str4)
return str4
}
//print(myAr)
}
}
}
if str.contains("-") {
print("(str.contains(-))")
let myArr = str.componentsSeparatedByString("-")
if myArr.count > 0 {
let str1 = myArr[0]
if str1.contains(":") {
print("str1.contains(:)")
let myAr = str1.componentsSeparatedByString(":")
if myAr.count > 0 {
let str2 = myAr[0]
let str3 = myAr[1]
let str4 = "\(str2):\(str3)"
print(str4)
return str4
}
//print(myAr)
}
}
}
}
}
// End - Its a temporary solution
I want a better solution instead of my temporary one.
Edit1:
As I mentioned, I want same time coming in JSON response by discarding the timezone.
Please suggest me and guide me how to deal with time zone in future. Hope you guys understand, what am I upto. Sorry for my poor English.
Thanks in Advance.
If you absolutely don't care about the timezone, you can simply trim it off:
let sunrise = "2016-07-10T08:05:02-0300"
let sunriseNoTimezone = sunrise.substringToIndex(sunrise.endIndex.advancedBy(-5))
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
let date = formatter.dateFromString(sunriseNoTimezone)
print(date)
Try below line of code. Hope it will help you...
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
dateFormatter.timeZone = NSTimeZone.systemTimeZone()
guard let date = dateFormatter.dateFromString(dateString)
else {
assert(false, "no date from string")
}
dateFormatter.dateFormat = "HH:mm"
return dateFormatter.stringFromDate(date)