Unexpected Value from Nsdate

Unexpected value from NSDate

Because there is a mass of question related to NSDate on SO and they all have the same shade, I will give you a longer answer, probably this can be referred from other questions.

A. There is a common misunderstanding, what a date is: A date is a point on timeline. It does not deal with hours or minutes, it does not deal with days, month, years, it does not deal with timezones.

It is a point on a timeline. Period.

(And internally it is represented by an floating-point number. Is that a surprise?)

B. There is another common misunderstanding, what a date is: Two dates, therefore points on a timeline, are equal, if the have the same value. This does not mean, that they have the same representation. Two times can be equal, even their representation is completly different. (This is, what happened to you.) For a comparison it does not matter, which timezone is in use, expected, $whatever. For a comparison is does not matter, which calendar is in use, expected or $whatever. If it is 11:11 in Cologne, Germany (UTC+1) it is 10:11 in London, England (UTC+0). This is the same time.

A date is earlier if it is on the timeline ahead of another date.

C. So what are these funny things like days, month, timezones and so on?
Since outside a star trek episode a time like 26,182,382,303.127373 would be difficult to understand and to handle, human beings began to give points on the timeline funny names. This representations are not the date. They are representations of the date. It is the same problem with numbers. Do you no this joke?

"There are 10 kind of people: Those, who understand binary numbers and those who doesn't."

The spirit of the joke is, that 10 can be the value of ten, if it is written in decimal notation or it can be the value of two, written in binary notation. Nobody can say, what value "10" denotes unless he knows the numeral system which is used for the representation. Most people assume, that it is in a decimal system, so "10" means ten. This is a popular convention. And this works fine since nearly all over the world adopted that convention. But: "10" can denote two different values. And the other way around, too: The same value can be written with different "strings": 10 in decimal notation is equal to 1010 in binary notation (and is equal to "2+8", sqrt(100), … That is, why it is allowed to write = between them.)

Unfortunaly (no, not really, time has to work locally in an easy way) for time there is no world-wide convention. If somebody writes "11:11" you simply cannot say, what time (remember, it is a point on the timeline) is meant. Probably the person implicitly says, that this is the time in his calendaric system in his timezone. But then you have to know, at which location on the world he is saying that. Taking day, month and so on in account, you probably have to know, what is his religion, because even in one country people of different religions uses different calendars.

Since there is no common world-wide convention on one hand and Mac OS is running on computer systems world-wide, you cannot assume, that a time printed out is written in a notation you expect.

Therefore it is completly, eh, not very intelligent to compare to dates by string. You do not compare dates, you compare strings.

Before you compare a time (including date) you have to transform the representation to a time to the "real" time. You have to add information about the calendar, the representation is written in and the timezone (which is included in the calendar in Cocoa).

In Cocoa you use instances of NSDateFormatter, NSCalendar, NSDateComponents to do this job. If you let NSDateFormatter transform a representation to a time and vice versa, you have to set the calendar. (NSDateFormatter assumes, that the local calendar is choosen, if you do not set one.) It is simply impossible to NSDateFormatter to do any transformation work, if it does not know which calendar to use. And it is simply impossible for you.

Then you can do some calculations with it, the date, the time, the instance of NSDate, including comparison and at least you have to transform it back into a human-readable representation using a calendar.

What you get and let you think, that it is a wrong time, is simply the correct time but in a represenatation you did not expect. (-description always delivers UTC+0).

NSDateFormatter Returning Unexpected Time Values

You are doing bad things by using both 24-hour format (HH) instead of 12-hour format (hh) and using AM/PM (a).

Change both instances of HH in your formats to hh and you should get the expected results.

You should also set the formatter's locale to the special locale en_US_POSIX to avoid issues with the device's 24-hour time setting.

Side note: Your use of NSMutableString is all wrong. Try this:

NSMutableString * theDateTime = [[NSMutableString alloc] init];
[theDateTime appendString:theDate];
[theDateTime appendString:@" "];
[theDateTime appendString:theTime];

or simply use:

NSString *theDateTime = [NSString stringWithFormat:@"%@ %@", theDate, theTime];

NSDateFormatter showing wrong date in ios?

Your local time zone is presumably UTC+5:30. You are specifying a date but not a time, so the time is implied to be midnight. Midnight on the 16th in your local time zone is 18:30 the day before (the 15th) in UTC time, which is why you get "2016-03-15 18:30:00 +0000"

When you log the date with NSLog(@"%@----",dateValue) you are actually invoking [dateValue description], which displays the date using UTC.

You can use NSLog(@"%@----",[dateValue descriptionWithCalendarFormat:nil timeZone:[NSTimeZone localTimeZone] locale:nil]) and you will see the date in your current time zone.

Be aware though that the description and associated methods such as descriptionWithCalendarFormat methods are only for debugging, you should use an NSDateFormatter to convert dates to strings. iOS_Binod's answer shows one way you could do this.

NSDateFormatter setDateFormat is not returning value correctly

You could get the right result as @RyanR described above.

In case you still prefer string as input, you need to tell your formatter the format of the input, and then convert string to NSDate first

let string = "2016-03-12 01:13:36 +0000"
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd hh:mm:ss +zzzz"
let date = formatter.dateFromString(string)

Once you have NSDate value, you can convert it to whatever format you like. In your case, if you want to have MM/dd/yyyy, then:

formatter.dateFormat = "MM/dd/yyyy"
let resultValue = formatter.stringFromDate(date!)

This code above give you exactly what you expected

About date format pattern, you could take a look at this link

Unexpected result after formating string to date

Set the locale and timezone to avoid invalid results. The return value of the extension should be Date? since the string may not be a valid date.
And since dateFormat is not optional, it should be a valid date format, see here for more details.

import UIKit

extension String {
func toDate(dateFormat: String, locale : Locale? = nil, timezone: TimeZone? = nil) -> Date? { //locale and timezone are optional with a default nil value
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.locale = locale
dateFormatter.timeZone = timezone
return dateFormatter.date(from: self)
}
}

You can use it like so:

let string = "01/24/2018 09:59:24"
let myLocale = Locale(identifier: "en_US_POSIX")
let myTimeZone = TimeZone(abbreviation: "PCT")

print(string.toDate(dateFormat: "MM/dd/yyyy HH:mm:ss",
locale: myLocale,
timezone: myTimeZone))

Handling fatal error: unexpectedly found nil while unwrapping an Optional value when creating a date object from a date string

NSDateFormatter's dateFromString returns an optional NSDate. Your let startDate:NSDate! states that startDate will never be nil, but dateFromString is returning nil.

The reason why dateFromString is returning nil is because your date format string is wrong. Try "yyyy-MM-dd HH:mm:ss" as Leo suggested in the comments, and consider making startDate an optional NSDate, only unwrapping it if it is non-nil.

NSDateFormatter doesRelativeDateFormatting returns unexpected relative day value

Your output is correct. Call anyone on the phone anywhere in the world and ask them what the date is and they will all say "today". Just because it's a different day of the week in two parts of the world doesn't mean it isn't "today" locally everywhere.

You are letting yourself get confused by comparing the output of two different timezones that happen to be in two different days when the code is run.

The idea of "relative" date formatting is that the output is a string relative to "now" in the given timezone. It's not relative to any other timezone. Whichever one is set on the date formatter.

Swift 2.1 DatePicker NSDate Error Nil Unwrapping Optional Value?

Dates are set in your date picker but your dates object is probably nil. You have just declared the dates object, so unless you allocate memory and initialise it, it will be nil. Do

var dates = Dates()

That will fix that error



Related Topics



Leave a reply



Submit