Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDatePicker return wrong NSDate

I am using UIDatePicker in my app and when i take the date that was chosen with:

NSDate *date = picker.date;

picker.date returned the day before the date that I chose.

any idea why it happens?

like image 977
YosiFZ Avatar asked Dec 02 '11 12:12

YosiFZ


4 Answers

UIDatePicker will be displaying dates and times in your local timezone. However, NSDate does not have any concept of a timezone as it stores an absolute number of seconds since a reference date. When NSLogging a date, it shows the date and time in GMT. I expect if you work out your local timezone difference from GMT, you will see that it is the correct date.

Try creating an NSDateFormatter or NSCalendar with the appropriate locale and pass the date through that.

For further reading on this common topic, see this site written by another SO contributor.

like image 182
jrturton Avatar answered Oct 06 '22 08:10

jrturton


give this a try worked for me

        NSDate* sourceDate = [NSDate date];

        NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
        NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

        NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
        NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
        NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;

        NSDate* destinationDate = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] autorelease]; 

//i'm outputting mine in a label you can use anything you like

        NSString *dateOutput = [[[NSString alloc] initWithFormat:@"%@", destinationDate]autorelease];
        self.dateLabel.text = dateOutput;
like image 37
Omer Janjua Avatar answered Oct 06 '22 07:10

Omer Janjua


Remember to create the NSDate and then output it with a valid timezone and calendar!

NSDate only represents an absolute point in time. It has no concept of timezone (NY, Barcelona, ...) or calendar (Gregorian, Hebrew, ...).

UIDatePicker returns by default a NSDate with the system NSCalendar and NSTimeZone, but when you try to print it later, you do not format the output. You may have there the mismatch.

So 1st you need to setup the UIDatePicker correctly and 2nd transform the output with the NSDateFormatter so it knows the Calendar and the TimeZone being used.

An example code with the init of the UIDatePicker and then printing the result:

- (void)viewDidLoad
{
   [super viewDidLoad];

   // init the UIDatePicker with your values 
   // by default UIDatePicker inits with today, system calendar and timezone
   // Only for teaching purposes I will init with default values
   NSDate * now = [[NSDate alloc] init];
   [_datePicker setDate: now] 
               animated: YES];       

   _datePicker.timeZone = [NSTimeZone localTimeZone];
   _datePicker.calendar = [NSCalendar currentCalendar];

   [_datePicker addTarget: self 
                   action: @selector(getDatePickerSelection:) 
         forControlEvents:UIControlEventValueChanged];

}   


-(void)getDatePickerSelection:(id) sender
{

   // NSDateFormatter automatically inits with system calendar and timezone
   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   // Setup an output style
   [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
   [dateFormatter setTimeStyle:NSDateFormatterShortStyle];

   // Medium style date, short style time => "Nov 23, 1937 3:30pm"
   NSString *dateString = [dateFormatter stringFromDate:date];

}

Check the answer I did for another very similar question:

NSDate output using NSDateFormatter

like image 42
Carlos Morales Avatar answered Oct 06 '22 09:10

Carlos Morales


Did you check the timezone?

When you print an NSDate it will use GMT as it timezone.

If you set the system timezone to the NSDateFormatter you might get an other date, because it will take the timezone and calculate the time accordingly.

Add this code and see if the output is correct:

NSDate *date = picker.date;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:NSDateFormatterNoStyle];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSLog(@"Date: %@", [dateFormmater stringFromDate:date]);
[dateFormatter release], dateFormatter = nil;
like image 41
rckoenes Avatar answered Oct 06 '22 08:10

rckoenes