Swift language bug in DateFormatter? [duplicate] - swift

This question already has answers here:
1st april dates of 80s failed to parse in iOS 10.0
(1 answer)
Why NSDateFormatter is returning null for a 19/10/2014 in a Brazilian time zone?
(3 answers)
DateFormatter's returns nil for specific date strings without time in Swift
(1 answer)
Closed 5 years ago.
I was testing an app that has an UITextField where users enter a date, so I take the entered string and use a DateFormatter to generate a Date object.
The problem first occurred when I tried converting the string "10/15/2017" which returned a nil value. So I create a code to generate string from "01/01/2000" to "12/31/2020" and I realized that the problem is occurring in all years around October or November of each year.
I created a code to print all dates that return a nil value:
import UIKit
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.locale = Locale(identifier: "en_US")
for day in 1...30 { // Generate the days
for month in 1...12 { // Generate the months
for year in 2000...2020 {
if month == 2, day > 28 { // Check if month is february
continue
}
str = "\(String(format: "%02d", month))/\(String(format: "%02d", day))/\(String(format: "%02d", year))"
let date = dateFormatter.date(from: str)
if date == nil {
print("\(str)")
}
}
}
}
I also tried changing the dateFormat, or even the locale properties and I'm also getting nil for some entries.
dateFormatter.dateFormat = "MM/dd/yyyy"
This snippet of code prints the following:
11/02/2004
11/03/2002
11/05/2006
10/08/2000
10/14/2001
10/14/2007
10/15/2017
10/16/2005
10/16/2011
10/16/2016
10/17/2010
10/18/2009
10/18/2015
10/18/2020
10/19/2003
10/19/2008
10/19/2014
10/20/2013
10/20/2019
10/21/2012
10/21/2018
I'm using Xcode 8.3.3 and Swift 3. Is that a bug with Swift/Xcode or I'm doing something wrong?

It's most likely the Brazil-Fall-Syndrome
The daylight saving changes in Brazil occur at midnight. In fall, when the clock is set forward, there is no 12:00 am / 0:00 so the date is nil.
Set the time zone to a country where daylight saving changes don't occur at midnight or set the hour to noon

Related

Getting start of month and end of month with time for December [duplicate]

This question already has answers here:
NSDateFormatter show wrong year
(1 answer)
first and last day of the current month in swift
(11 answers)
Getting back a date from a string
(3 answers)
Closed 2 years ago.
As the title indicates I'm trying to get the start and end of month with a time component for December. I'm sure I'm missing something obvious related to TimeZones but I can't seem to get a same year for both dates in in PST time zone.
Here's how I get the start of month and day:
NOTE: If you try this in the swift REPL there's a bug that shows nil result even though the
variables have a non-nil value, use print or debugPrint to show the value.
let cal = Calendar.current
let startOfMonth = cal.startOfDay(for: cal.date(from: DateComponents(year: 2020, month: 12, day: 1))!)
Here's how I calculate the end of day up to seconds:
let startOfNextMonth = cal.date(byAdding: DateComponents(month: 1), to: startOfMonth)!
let endOfMonth = cal.date(byAdding: DateComponents(second: -1), to: startOfNextMonth)!
By this point startOfMonth has the value: Optional(2020-12-01 08:00:00 +0000) and endOfMonth has a value of Optional(2021-01-01 07:59:59 +0000)
Which seems fine and dandy because times are printed in GMT (UTC) and if I subtract 8 hours endOfMonth it would end up like Optional(2020-12-31 23:59:59 +0000)
However the trouble comes when formatting the endOfMonth date, even If I set the TimeZone to "America/Los_Angeles" I still get the year value as 2021 and not as 2020, here's how I create my formatter:
let fmt = DateFormatter()
fmt.timeZone = .current // "America/Los_Angeles"
fmt.dateFormat = "d/Y"
fmt.string(from: endOfMonth!) // $R13: String = "31/2021"
What's going on?, wouldn't conversion to the default Time zone yield the year 2020?
After setting the formatter dateStyle property to .long and obtaining the correct year printed (though not the format I wanted) I realized that the issue might be in the dateFormat.
After reading a bit more of the documentation, I found a link to the format specifiers
Date Format Swift Docs
Date Formatting Guide
Unicode Date Format Patterns
Eventually I found out that the Y specifier is essentially a "Week of Year" vs the y specifier which is "Year of Era".
Using the following fixed my issue:
let formatter = DateFormatter()
formatter.dateFormat = "d/y"
formatter.string(from: endOfMonth!) // $R1: String = "31/2020"

Why does print(date object) show a different date than what the value actually is? [duplicate]

This question already has answers here:
NSDate() or Date() shows the wrong time
(2 answers)
Closed 2 years ago.
I am playing around with DateFormatter in xcode playground to try to learn the basic of how the date object works in swift.
The following code gave my strange results when i tried to print the result from a string to date conversion from this string "050478" (5. April 1978) to a date . In Norway our social security number starts with ddMMyy, so it is that number i want to convert to a date.
import UIKit
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "dd/MM/yy"
let myDateString = "05/04/78"
if let myDate = dateFormatterGet.date(from: myDateString)
{
print(myDate)
}
As you can see, the print(myDate) command gives me the wrong date from the day before what i a gave as argument to the dateformatter (1978-04-04)
The local time zone in Norway on May 5th at 0:00 is UTC+0100.
However print() displays dates always in UTC(+0000) which is May 4th at 23:00.
Replace
print(myDate)
with
print(myDate.description(with: .current))
to get the local date and time

Big int to date time format in swift [duplicate]

This question already has answers here:
How to Convert UNIX epoch time to Date and time in ios swift
(3 answers)
Closed 2 years ago.
I am doing this in swift:
let date = NSDate(timeIntervalSince1970: 1432233446145.0)
println("date is \(date)")
The log gives me this:
date is 47355-09-02 23:55:45 +0000
Then I try to get an interval back out just for testing:
let tI = expirationDate.timeIntervalSinceDate(date)
println("tI = \(tI)")
I get:
tI = 0.0
What am I doing wrong?
I can seem to make the timeIntervalSince1970 call work properly. Is there any known issued with that in Swift, or am I missing something here?
1432233446145 most probably is a time interval given in milliseconds:
let date = NSDate(timeIntervalSince1970: 1432233446145.0/1000.0)
print("date is \(date)")
// date is 2015-05-21 18:37:26 +0000
Swift 3 and later:
let date = Date(timeIntervalSince1970: 1432233446145.0/1000.0)
I think your timestamp is incorrect. This results in your date being september 2nd, 47355.
If I use the following I get the date for (right about) now:
let date = NSDate(timeIntervalSince1970: 1431024488)
println("date is \(date)")
// "date is 2015-05-07 18:48:08 +0000"
The printed date is not a localized timestamp, so you'll have to do some localization of your own I suppose. An example:
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
println("formatted date is \(formatter.stringFromDate(date))")
// "formatted date is 07-05-2015 20:48:08"
And for completeness I also checked with an expiration date that's 1100 seconds larger than the initial date:
let expirationDate = NSDate(timeIntervalSince1970: 1431025588)
let diff = expirationDate.timeIntervalSinceDate(date)
println("expires in: \(diff)")
// "expires in: 1100.0"
So, the timeIntervalSince1970 seems to work fine, I think your interval was just not what you wanted it to be.
From your code and the log content follows:
date.isEqual(expirationDate)
--> Your stuff has just expired :-).

NSDate timeIntervalSince1970 not working in Swift? [duplicate]

This question already has answers here:
How to Convert UNIX epoch time to Date and time in ios swift
(3 answers)
Closed 2 years ago.
I am doing this in swift:
let date = NSDate(timeIntervalSince1970: 1432233446145.0)
println("date is \(date)")
The log gives me this:
date is 47355-09-02 23:55:45 +0000
Then I try to get an interval back out just for testing:
let tI = expirationDate.timeIntervalSinceDate(date)
println("tI = \(tI)")
I get:
tI = 0.0
What am I doing wrong?
I can seem to make the timeIntervalSince1970 call work properly. Is there any known issued with that in Swift, or am I missing something here?
1432233446145 most probably is a time interval given in milliseconds:
let date = NSDate(timeIntervalSince1970: 1432233446145.0/1000.0)
print("date is \(date)")
// date is 2015-05-21 18:37:26 +0000
Swift 3 and later:
let date = Date(timeIntervalSince1970: 1432233446145.0/1000.0)
I think your timestamp is incorrect. This results in your date being september 2nd, 47355.
If I use the following I get the date for (right about) now:
let date = NSDate(timeIntervalSince1970: 1431024488)
println("date is \(date)")
// "date is 2015-05-07 18:48:08 +0000"
The printed date is not a localized timestamp, so you'll have to do some localization of your own I suppose. An example:
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
println("formatted date is \(formatter.stringFromDate(date))")
// "formatted date is 07-05-2015 20:48:08"
And for completeness I also checked with an expiration date that's 1100 seconds larger than the initial date:
let expirationDate = NSDate(timeIntervalSince1970: 1431025588)
let diff = expirationDate.timeIntervalSinceDate(date)
println("expires in: \(diff)")
// "expires in: 1100.0"
So, the timeIntervalSince1970 seems to work fine, I think your interval was just not what you wanted it to be.
From your code and the log content follows:
date.isEqual(expirationDate)
--> Your stuff has just expired :-).

swift stored date turns different when formatted to string [duplicate]

This question already has answers here:
NSDate Format outputting wrong date
(5 answers)
Closed 7 years ago.
I stored a date in core data (as a date), and with the println it shows correctly its value: april 21 (is the var dateX below), but when right after the println i format it to string with the following code, the label linked to it shows april 22 (which is today, so i wonder tomorrow will show 23 etc.), where is the problem? anyone?
thank you
if dateX != nil{
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM dd, yyyy"
dateFormatter.timeZone = NSTimeZone.defaultTimeZone()
var dateXstring = dateFormatter.stringFromDate(dateX as NSDate)
startLabel.text = "Profile created on \(dateXstring)"
}
println dateX and dateXstring:
my time zone is Rome (Italy)
You likely have a timezone issue. Where are you located? DefaultTimeZone could be GMT/ZULU time which is -5 hrs from the east coast.
A good way to check is to use the timeIntervalSince1970 function (i think thats what it is called). If the stored date and retrieved date have the same value its the same date and you have a display problem.
timeIntervalSince1970 returns a NSTimeInterval which is really a Double