Bug in swift 2.0 NSDateFormatter? [duplicate] - swift

This question already has an answer here:
DateFormatter's returns nil for specific date strings without time in Swift
(1 answer)
Closed 7 years ago.
NSDateFormatter doesn't seem to like October Eighteenth. Tried every other date with success. (???)
It is almost certainly a bug in swift 2.0 (and if it is what should I do? I need to submit my app really soon). Am I missing something?
Checked it in playground on Xcode 7.0.1:
let str = "2015-10-18"
let str2 = "2015-10-14"
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
var date = formatter.dateFromString(str)
var date2 = formatter.dateFromString(str2)
Output:
"2015-10-18"
"2015-10-14"
<NSDateFormatter: 0x7f8aa050b760>
<NSDateFormatter: 0x7f8aa050b760>
<NSDateFormatter: 0x7f8aa050b760>
nil
"Oct 14, 2015, 12:00 AM"

The behavior depends on which timeZone the formatter using.
For example: America/Sao_Paulo
In Sao Paulo, http://www.timeanddate.com/time/change/brazil/sao-paulo?year=2015
Sunday, 18 October 2015, 00:00:00 clocks are turned forward 1 hour to
Sunday, 18 October 2015, 01:00:00 local daylight time instead
That means, there is no 2015-10-18 00:00:00 in Sao Paulo.
And as for NSDateFormatter, when it receives no time information from string, it assumes the time is 00:00:00 in its timezone. That's why it returns nil.
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(name: "America/Sao_Paulo")
formatter.dateFormat = "yyyy-MM-dd HH:mm"
formatter.dateFromString("2015-10-18 00:00") // -> nil
formatter.dateFromString("2015-10-18 00:30") // -> nil
formatter.dateFromString("2015-10-18 01:00") // -> non nil
As #LeoDabus stated, when you specify .calendar on the formatter:
it assumes the time is 00:00:00 in its timezone.
it will assume the start of the day for that date.
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(name: "America/Sao_Paulo")
formatter.dateFormat = "yyyy-MM-dd"
formatter.calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
formatter.dateFromString("2015-10-17") // -> Oct 17, 2015, 12:00 AM
formatter.dateFromString("2015-10-18") // -> Oct 18, 2015, 1:00 AM
formatter.dateFromString("2015-10-19") // -> Oct 19, 2015, 12:00 AM

Related

Swift Convert UTC string to UTC Interval

I am getting UTC date in string format from server which is "Sep 8 2022 10:14AM"
Now I want to convert it into same time interval like this 1662632040.
Below Is my code I am not getting why I am getting different time interval
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd yyyy HH:mma"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let dt = dateFormatter.date(from: "Sep 8 2022 10:14AM")!
let interval = dt.timeIntervalSince1970
interval is giving result 1662596040 but correct one is 1662632040.
I am not getting what is missing

How do you display date in this format? "Jul 18, 2018 at 10:02 AM"

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "UTC")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = dateFormatter.date(from: "2018-07-18T17:02:02.614Z")
date description prints: 2015-06-18 17:02:02 +0000
Playground seems to naturally outputs this on the right side: "Jun 18, 2015 at 10:02 AM"
How do I format it to display this? "Jul 18, 2018 at 10:02 AM"
Thanks!
You need to format date (which is now a Date instance) using another DateFormatter. And you should use date and time styles, not a fixed format for this.
And "UTC" is not a locale, it's a timezone. But you don't need that. But you should use the special locale of en_US_POSIX when parsing a fixed format date string.
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = dateFormatter.date(from: "2018-07-18T17:02:02.614Z")
if let date = date {
let outputFormatter = DateFormatter()
outputFormatter.dateStyle = .medium
outputFormatter.timeStyle = .short
let output = outputFormatter.string(from: date)
print(output)
}
Output:
Jul 18, 2018 at 11:02 AM
Note that the time will depend on your local timezone. By default the output will be in local time so don't expect the output to be 17:02 since that is the time in the UTC timezone.

How to convert 2 Strings (date and time) into one NSDate object in Eastern Time Zone in Swift

I have the following code to convert a String with a date like April 22, 2017 and a second String with the time 4:30 PM and I need to convert these 2 Strings into one complete NSDate object in the Eastern Time Zone.
//convert scheduled date and time from String to NSDate
let scheduledServiceDateStr = orderReview.serviceDate //current format example: April 21, 2017
let scheduledServiceTimeStr = orderReview.serviceTime //current format example: 04:30 PM
print("scheduledServiceDateStr: \(scheduledServiceDateStr)")
print("scheduledServiceTimeStr: \(scheduledServiceTimeStr)")
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMMM d, yyyy"
dateFormatter.timeZone = NSTimeZone(name: "EST")
let scheduledServiceDate = dateFormatter.dateFromString(scheduledServiceDateStr)
print("scheduledServiceDate: \(scheduledServiceDate)")
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "hh:mm a"
timeFormatter.timeZone = NSTimeZone(name: "EST")
let scheduledServiceTime = timeFormatter.dateFromString(scheduledServiceTimeStr)
print("scheduledServiceTime: \(scheduledServiceTime)")
let timeComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Second], fromDate: scheduledServiceTime!)
let dateComponents = NSCalendar.currentCalendar().components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: scheduledServiceDate!)
// append the time to the date
dateComponents.hour = timeComponents.hour
dateComponents.minute = timeComponents.minute
dateComponents.second = timeComponents.second
let dateAndTime = NSCalendar.currentCalendar().dateFromComponents(dateComponents)
print("dateAndTime: \(dateAndTime)")
This is what is printed in the Console:
scheduledServiceDateStr: April 22, 2017
scheduledServiceTimeStr: 04:30 PM
scheduledServiceDate: Optional(2017-04-22 05:00:00 +0000)
scheduledServiceTime: Optional(2000-01-01 21:30:00 +0000)
dateAndTime: Optional(2017-04-21 20:30:00 +0000)
The issue I am having is that the ending result, the dateAndTime NSDate value displayed in the console at the end is 2017-04-21 20:30:00 +0000 but, the time 20:30:00 I believe is equivalent to 8:30 PM Eastern Time when the time originally selected was 4:30 PM. I understand that NSDate does not take Time Zones into account and that it is just a representation of of seconds since January 1, 2001. As you can see I am setting the Time Zone to EST before converting each String to an NSDate object. What am I doing wrong?
I don't think there's anything wrong with the time. EST is -04:00 so 16:30 EST = 20:30 GMT. And you wrote way more code that needed to be:
let scheduledServiceDateStr = "April 21, 2017"
let scheduledServiceTimeStr = "04:30 PM"
let formatter = DateFormatter()
formatter.dateFormat = "MMM dd, yyyy hh:mm a"
formatter.timeZone = TimeZone(identifier: "EST")
if let date = formatter.date(from: scheduledServiceDateStr + " " + scheduledServiceTimeStr) {
print(date)
}

Swift Format Date

This is probably really simple, I have tried lots of different methods but it doesnt seem to work.
I have the following date format in a text field:
Saturday, 2 January 2016 12:00
held as:
var str = "\(dobTextField.text!)"
I would like to convert the string above into the format:
YYYY-mm-dd
any help would be much appreciated!
For Swift 2
Check this :
let str = "Saturday, 2 January 2016 12:00"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEEE, d MMMM yyyy HH:mm"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let outputA = dateFormatter.dateFromString(str)
dateFormatter.dateFormat = "yyyy-MM-dd"
println(dateFormatter.stringFromDate(outputA!))
Output :
2016-01-02

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?