0

This is my code.

NSString *dateString = @"2015-06-03 02:19:37";

NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];

NSLog(@"converted date = %@",[formatter dateFromString:dateString]);

The output of the code above is: "converted date = 2015-06-02 18:19:37 +0000". I know that this is because it converts the NSString with respect to GMT, but what i wanted to happen is NSDate must be 2015-06-03 02:19:37, same with dateString

Romz
  • 71
  • 5
  • 4
    So you say you understand why it's displaying the wrong time, but still state that the converted `NSDate` object is wrong. You clearly don't understand why. Please search as this is a very common issue. – Droppy Jun 03 '15 at 06:40
  • You can change the timezone of your formatter. – Groot Jun 03 '15 at 06:51
  • @Droppy, i didn't say it is wrong, the converted NSDate object is correct however, what i want as the value of NSDate is 2015-06-03 02:19:37 not the converted NSString to NSDate. – Romz Jun 03 '15 at 06:59
  • Well you said "NSDate must be 2015-06-03 02:19:37" which implies the date object is wrong. What you need to do is use the date formatter to format the dates (i.e. `NSDate` to `NSString`). – Droppy Jun 03 '15 at 07:02

4 Answers4

2

I know that this is because [the NSDateFormatter] converts the NSString with respect to GMT…

No, you're wrong. NSDateFormatter defaults to using your current time zone.

What you're not understanding is that "2015-06-02 18:19:37 +0000" is the same date and time as "2015-06-03 02:19:37" (in your local time zone, which must be GMT+0800).

Also, the description that you logged is just one representation of the date. The date does not have a year, month, day-of-month, hour, minute, second, or any of that. A date object just represents a moment in time. Such moments don't have any of that and neither do NSDate objects. Only representations of moments have those things, and they are only arrived at by processing the date through a specific calendar and time zone. In any case, any given date has multiple representations. Just because the description that gets logged happens to choose a representation that you weren't expecting doesn't mean the date is wrong.

You have implicitly requested a conversion from an NSDate object to a string when you logged it. That's because logging always involves strings. The string-formatting code used by NSLog() and the %@ format specifier uses the -description method. You are never going to be able to force NSDate's implementation of -description to use your time zone, so don't try.

If you really need a string representation (and you're not just debugging) and you want it in some specific time zone or otherwise want to dictate the format, don't rely on the -description method like you are. Instead, use a date formatter to convert from NSDate to an NSString explicitly, and configure the date formatter to produce the representation that you want.

But don't confuse the need to do that with the date being wrong.


What I really wanted to do is to check if the given NSDate is already past 9PM EST (-4GMT), while i'm on +8GMT timezone.

So, use NSCalendar, NSTimeZone, and NSDateComponents to construct an NSDate for 9PM EST (on the current day, I suppose you mean) and then compare the dates.

NSDate* date = /* ... */;
NSCalendar* calendar = [[NSCalendar alloc] initWithIdentifier:NSCalendarIdentifierGregorian];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"America/New_York"];
NSDate* deadline = [calendar dateBySettingHour:21 minute:0 second:0 ofDate:date options:0];
if ([date compare:deadline] == NSOrderedDescending)
    /* date is after deadline */;

Here I used the convenience method -dateBySettingHour:minute:second:ofDate:options: and avoided direct use of NSDateComponents. If your needs differ, you might have to convert the date to date components using the calender, modify the components, convert them back to a date, and then compare.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • i see, so i'll just create another instance of NSDate with a custom date, and not depending on the dateString since dateString if converted to NSDate returns the correct value (which is not what I want to get). – Romz Jun 03 '15 at 07:17
  • I don't understand what you mean. You don't want the "correct value"? What do you want? For what purpose will you be using the date object? – Ken Thomases Jun 03 '15 at 14:20
  • What I really wanted to do is to check if the given NSDate is already past 9PM EST (-4GMT), while i'm on +8GMT timezone. that's why i want to create an NSDate object that has the exact value of dateString so i can compare it to [NSDate date] accurately. Well, i don't want to hardcode the +8GMT because i can be anywhere. – Romz Jun 04 '15 at 03:01
-1

Use the NSDateComponents class to build the date from the information in the string. The documentation explicitly provides an example of this:

NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:6];
[comps setMonth:5];
[comps setYear:2004];
NSCalendar *gregorian = [[NSCalendar alloc]
    initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
NSDateComponents *weekdayComponents =
    [gregorian components:NSWeekdayCalendarUnit fromDate:date];
int weekday = [weekdayComponents weekday];
Michael
  • 6,561
  • 5
  • 38
  • 55
-1

call this method with your string value...

 - (NSDate *)dateFromString:(NSString *)date
        {
            static NSDateFormatter *dateFormatter;
            if (!dateFormatter)
            {
                dateFormatter = [[NSDateFormatter alloc] init];
                [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
                [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
                [dateFormatter setDateFormat:@"dd-MM-yyyy"];
            }

            NSLog(@"Date: %@",date);

            return [dateFormatter dateFromString:date];
        }


    RESULT : Date: 2015-06-03 02:19:37
NaniBhai
  • 3
  • 3
  • this returns nil, and by the way, the reason why you got the logged right is because you are logging the date not the [dateFormatter dateFromString:date]. – Romz Jun 03 '15 at 07:11
-2
NSString *dateString = @"2015-06-03 02:19:37";     
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd"];
 NSDate *startDate = [f dateFromString:dateString];

You will get the NSDate here(startDate).... May this help to you.....

NaniBhai
  • 3
  • 3