2

I'm trying to store a time in a date. In this case 1.5 seconds. I store the time in the date like this:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];  
NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"];

But if I look in the debug area I can see that the value of date1 was set to:

date1 = (NSDate *) 0x1dd32b30 2000-01-01 01:00:01 CET

Could anyone tell me why this is happening?

MatisDS
  • 91
  • 1
  • 11
  • 2
    The description of `NSDate` doesn't handle timezones. You rather want to convert the date back to a string using another call to `NSDateFormatter`. –  Jun 25 '13 at 10:01
  • Yes but I'm making a game and if your time to complete the level is lower than 1.5 seconds you will get 3 stars. So I have also another NSDate and that is the date that was needed to complete the level. And I don't know how I can check if the player's time was lower than my time with NSStrings. – MatisDS Jun 25 '13 at 10:05
  • You don't. You use `[date1 compare:date2]`. –  Jun 25 '13 at 10:05
  • Yes I use it but I didn't put it in the question I will edit my post. – MatisDS Jun 25 '13 at 10:06
  • Then what's the problem? –  Jun 25 '13 at 10:06
  • Date1 gets the value of 01:00:01 instead of 00:01.50 and I can't compare if date 1 has a wrong value. – MatisDS Jun 25 '13 at 10:13
  • It doesn't have a wrong value. Read my first comment. –  Jun 25 '13 at 10:14
  • But how can I set the date of date1 to 00:01.50 instead of 01:00:01 – MatisDS Jun 25 '13 at 10:28
  • What to you mean by "to set the date"? –  Jun 25 '13 at 10:29
  • store 00:01.50 in date1 – MatisDS Jun 25 '13 at 10:30
  • You have already done that. –  Jun 25 '13 at 10:31
  • But why do I get the value 01:00:01? Do I have to delete this sentence: [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; ? – MatisDS Jun 25 '13 at 10:33
  • Still my first comment. –  Jun 25 '13 at 10:34
  • Thanks but what do I have to change can you give me the code please? I am quite new to Objective-C. :) – MatisDS Jun 25 '13 at 10:36
  • You don't have to do anything further. The date is printed incorrectly but it contains the right date in fact. If you want a string, convert it back using `NSDateFormatter` but again, I've already told you that. –  Jun 25 '13 at 10:37

2 Answers2

6

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).

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • Thanks for your answer! It helped me I already have found a solution to compare the dates and thanks to you I know that the time is correct because I live in Belgium and not in Greenwich. Thank you very much! – MatisDS Jun 25 '13 at 12:22
0

Trying NSLog on date will return date in GMT format only. So if you want to check if you are getting the correct time or date, convert date to string and NSLog.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];  
NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"];

NSString *dateString = [dateFormatter stringFromDate:date1];
NSlog(@"%@",dateString);
prince
  • 854
  • 2
  • 9
  • 36