UIDatePicker return wrong NSDate

2019-02-17 13:38发布

问题:

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?

回答1:

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.



回答2:

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;


回答3:

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



回答4:

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;


回答5:

Just add one line of code

self.datePicker.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

0 is for GMT 00 . Add according to your time zone.