Date format issue with NSDateFormatter - swift

I have this code:
var d = "22/12/1968 01:10:40"
var form : NSDateFormatter = NSDateFormatter()
form.dateFormat = "dd/MM/yyyy HH:mm:ss"
form.timeZone = NSTimeZone.localTimeZone() //Italy
print(form.dateFromString(d)!)
When I execute it I get this:
1968-12-22 00:10:40 +0000
first thing Why do I get "+0000" at end? and why the data format isn't respected?
Second , the time is wrong.
It's like the time is setted on London's time , but instead I setted it on my local time zone ( italy).
I tested it on iPhone Simulator

Why the date is wrong?
var d = "22/12/1968 01:10:40"
var form : NSDateFormatter = NSDateFormatter()
form.dateFormat = "dd/MM/yyyy HH:mm:ss"
//until here, there is no "problem"
form.timeZone = NSTimeZone.localTimeZone() //Italy //it means, the datetime is 22/12/1968 01:10:40 in Italy (GMT +1)
//Remember that NSDate is absolute time, or it holds GMT+0 time.
//As now, in Italy, it's 22/12/1968 01:10:40, then in GMT+0 time, it's 1h later. So, testDate holds 22/12/1968 00:10:40
NSDate testDate = form.dateFromString(d)!
Why it does not print the same format?
Because you did not use your NSDateFormatter object to get back date string but you used print() to print out directly the description of your object NSDate.

Related

Swift Date formating changes to next month when using end of month data?

I live by end of month dates such as "2019-02-28 23:59:59"
print when I print out that date it tells me "Mar-2019". No it is still "Feb-2019"
print(dt1.toString(dateFormat: "MMM-YYYY")
I do use SwiftDate. I also get this issue with the DateFormatter().
so instead of clean code I end up having to subtracting a day to get the correct month-year to display.
Why?
You need to set Timezone & date format properly as below,
let string = "2019-02-28 23:59:59"
let df = DateFormatter()
df.timeZone = .current
df.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = df.date(from: string)
print(date?.description(with: .current)) //Thursday, February 28, 2019 at 11:59:59 PM Gulf Standard Time
df.dateFormat = "MMM-yyyy"
print(df.string(from: date!)) // Feb-2019

How to get a date from European time-only with DateFormatter in Swift

I try to get a date but I only have a time available.
For now, I don't care about year, month or day. All that matters is the time.
My input is in the form "hh:mm:ss" (i.e. European time format).
The problem is that any time above 12:59:59 does not work !
How can I get dates from times above 12:59:59 ????
My code looks like follows:
import UIKit
let str = "17:02:09"
let mydateFormatter = DateFormatter()
mydateFormatter.dateFormat = "hh:mm:ss"
let timezone = TimeZone(abbreviation: "CEST") ?? TimeZone.current
mydateFormatter.timeZone = timezone
mydateFormatter.locale = Locale(identifier: "de_DE") as Locale?
let date1 = mydateFormatter.date(from: str)
print(date1?.description ?? "no date available")
Output: no date available
If I set the str's hour setting to anything below or equal to 12, then it works.
For example, if I set str = "12:02:09", I get the output: 1999-12-31 23:02:09 +0000
For example, if I set str = "10:02:09, I get the output: 2000-01-01 09:02:09 +0000
For example, if I set str = "13:02:09, I get the output: no date available
How can I get dates from times above 12:59:59 ????
And ideally, how can I get dates that have a matching time with the input-time ?

Swift Date function do not work as Expected

I am trying to find out the difference between two date in seconds using Swift 4.1. This is the code I use,
func getDurationInSeconds(date1 :Date) -> Int{
guard let durationInSeconds = Calendar.current.dateComponents([.second], from: Date(), to: date1).second else {
return 0
}
return durationInSeconds
}
Function to generate date1 from 2018-10-09T18:19:00Z
func dateFromString(stringDate:String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale?
let date = dateFormatter.date(from: stringDate)
return date
}
The Date is always returning back an hour less than my current device time, so the calculation is not working as expected. If my current device time is 16:34 the Date() function returns it back as 15:34.
I have seen that Date() is returning back the time in UTC not based on my timezone.
At the moment if I pass in a Date 09/10/2018 14:25:00 and the current device time is 09/10/2018 14:20:00. I am expecting this function to return a value 300 which is 60 * 5 minute difference between two dates.
But I am getting back a value of 3900 which is because the date function returns the date as
09/10/2018 13:20:00 instead of 14:20
. So the duration will be 1 hour + the 300 second difference.
Including a sample output from Xcode console, my device time when I executed this code was 2018-10-09 17:56:28.565423
(lldb) po date1
▿ 2018-10-09 17:59:00 +0000
- timeIntervalSinceReferenceDate : 560800740.0
(lldb) po durationInSeconds
3731
(lldb) po Date()
▿ 2018-10-09 16:57:04 +0000
- timeIntervalSinceReferenceDate : 560797024.35021996
(lldb)
But I cant find a proper way to find the correct duration between two times based on my current time zone. How can I do it?
The issue is not with the Date() returning wrong time. Date() always returns the current time, which is not really based on your (any other) local timezone.
The problem seems to be with the dateFormatter that you are using to generate the Date object from the date string.
Please try using the following lines of code:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
// Not necessary as the dateFormatter would take the device's timeZone to be the default.
dateFormatter.timeZone = Calendar.current.timeZone
instead of:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
The problem with the latter is that, you are specifying 'Z' to be the zero-offset time zone (UTC). So, the difference of 1 hour from UTC in your device is causing this offset.
And, while passing in the date string, please make sure that you skip the 'Z' at the end (For example, it should be like 2018-10-09T18:19:00).
The updated code should work good for you, and return the expected difference in seconds.
Since you are using a string that represents the current time in your time zone, try this instead:
func getDurationInSeconds(date1: Date) -> Int {
return Int(-date1.timeIntervalSinceNow + TimeZone.current.daylightSavingTimeOffset(for: date1))
}
It uses this property and this method.
Or if you'd like to account for the time zone difference from UTC in dateFromString(stringDate:):
func getDurationInSeconds(date1: Date) -> Int {
return Int(-date1.timeIntervalSinceNow)
}
func dateFromString(stringDate:String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: stringDate)! //I am force-unwrapping for brevity
let adjustedDate = date.addingTimeInterval(-TimeZone.current.daylightSavingTimeOffset(for: date))
return adjustedDate
}
Test
I am in a UTC + 1h timezone:
let str = "2018-10-09T19:50:00Z" //"2018-10-09T19:50:00Z"
let date1 = dateFromString(stringDate: str)! //"Oct 9, 2018 at 7:50 PM"
Date() //At the time of testing this it is "Oct 9, 2018 at 7:53 PM"
getDurationInSeconds(date1: date1) //213, which is 3 minutes and 33 seconds

Date output is different.So,can't compare correctly

Here is my code.Please take a look first
import UIKit
var expireDate : Double = 1472647093
var date = NSDate(timeIntervalSince1970: expireDate)
print("Date : \(date)")
let current_date = NSDate()
if date.compare(current_date) == NSComparisonResult.OrderedDescending{
print("is Greater than current date")
}else if date.compare(current_date) == NSComparisonResult.OrderedAscending{
print("is Less than current date")
}else{
print("Same")
}
Here is the output on playground :
I really don't know why "Date : " output is different than date variable.My server send me an expire date format in unix timestamp which is long format.And I really need to compare it with current date.Actually
Aug 31, 2016, 7:08 PM // It has correct day/month/year but incorrect time
2016-08-31 12:38:13 +0000\n // has all correct time and date that the server send which was 12:38PM
So,why I am having greater than current date?And why it was 7:08PM instead of 12:38PM
Any help?
UPDATE :
You don't have wrong dates since Aug 31, 2016, 7:08 PM is your current timestamp, whereas in the print you have with timezone UTC. When you compare the dates they are both in UTC so you don't have any problems.
My above question has nothing wrong with it. I'm just misunderstood with the timezone or standard that I am dealing with. The server already send me expire date with my timezone locale in UTC standard format.
So,I don't need to change that expire date according to my current time zone.
All I have to do is get my current time,change it to UTC format using my current timezone. And compare server expire_date and current_date. Mission Accomplish.
// Using Expire Date
var expireDate : NSTimeInterval = 1472689452 // 00:24 AM UTC
var date = NSDate(timeIntervalSince1970: expireDate) // Since January 1 1970 Convert to NSDate
// Then I change this time format to UTC String without adding any timezone because its already included
var df_utc = NSDateFormatter()
df_utc.timeZone = NSTimeZone(name: "UTC")
df_utc.dateFormat = "yyyy.MM.dd G 'at' HH:mm:ss zzz"
// Get the expire date string by formatting it in UTC
var ts_utc_string : NSString = df_utc.stringFromDate(date)
// Getting current time of mine
var local_date = NSDate()
var df_local = NSDateFormatter()
df_local.timeZone = NSTimeZone(name: "MMT") // then use my locale to add that current time UTC [MMT +6:30]
df_local.dateFormat = "yyyy.MM.dd G 'at' HH:mm:ss zzz"
var ts_local_string : NSString = df_local.stringFromDate(local_date)
// Compare
if ts_local_string.compare(ts_utc_string as String) == NSComparisonResult.OrderedDescending{
print("CurrentTime is Greater than Expire Time")
}else if ts_local_string.compare(ts_utc_string as String) == NSComparisonResult.OrderedAscending{
print("CurrentTime is Less than Expire Time")
}else{
print("Same")
}
Here is the output :
For those who are still seeking for such problem like me, UTC was just a standard for timezone. If you need to compare it with your timezone, you just need to change your current time according to your country timezone.

date playground loses a day: SWIFT

I'm trying to play with dates, saving them as strings, then returning them to dates. my output loses a day. Please see below for the playground code:
let date = NSDate()
let formatter = NSDateFormatter()
let secondDateFormatter = NSDateFormatter()
formatter.dateStyle = .FullStyle
let dateString = formatter.stringFromDate(date)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEEE, MMMM dd, yyyy"
let finalDate : NSDate = dateFormatter.dateFromString(dateString)!
println(finalDate)
here's the current output:
date = May 7, 2015, 9:16 AM
dateString = "Thursday, May 7, 2015" (perfect)
let finalDate shows: "May 7, 2015, 12:00 AM" (almost perfect except the time)
println(finalDate) reveals : 2015-05-06 16:00:00 +0000
I've searched around and read that it is a time zone modification? I'm not sure. I'll play with it more and see if it works for my needs. Any idea why the output would be different when println is execute vs. just the calculation?