UIDatePicker возвращает неверную дату (-1 день до реальной даты)

У меня есть UIDatePicker mm/dd/yy. Он работает нормально, но есть одна проблема: я устанавливаю дату minimum и maximum, и когда пользователь пытается выбрать запрещенный день, месяц или год, свойство [datePicker date] начинает работать неправильно. Он возвращает вам current day - 1 или current month - 1 или current year - 1. Я добавил несколько фотографий, чтобы вы могли видеть ситуацию.

Correct date Это правильно
wrong date Это неправильно (после выбора запрещенной даты)

Кто-нибудь знает, как я могу это исправить? Спасибо!

UPD: Код

[self.myDatePicker setMinimumDate:[NSDate date]];
[self.myDatePicker setMaximumDate:[[NSDate date] addTimeInterval:2 * 365.25 * 24 * 60 * 60]]; // to get upto 5 years
NSDate * now = [[NSDate alloc] init];
[self.myDatePicker setDate: now animated: YES];

self.myDatePicker.timeZone = [NSTimeZone localTimeZone];
self.myDatePicker.calendar = [NSCalendar currentCalendar];

Ответ 1

Это действительно что-то с часовыми поясами и/или летним временем. Но он должен быть очень тонким, так как код выглядит отлично (рядом с интервалом). Теперь, к моему вопросу, если вы находитесь в россии:

В этом году Кремль сделал несколько отскоков назад и вперед, чтобы навсегда сохранить летнее время. На самом деле я не уверен, что они решили наконец. Но, возможно, это неверно отражено в Cocoa. Видео WWDC 2011 Video "Session 117 - Выполнение календарных вычислений" , ведущий даже упоминает, что такие вещи могут произойти.

Пожалуйста, постарайтесь работать с датами с установленным вручную временем до полудня, так как это избавит вас от такого беспорядка.


В мире только что было похожее неправильное поведение в iOS 6: ошибка DND-Always-Active. Уверен, что это был неправильный формат даты (YYYY вместо YYYY)


Также попробуйте установить свойство часового пояса на сборщике в самом первом месте и назначьте ему гринорианский календарь, созданный вручную.

Ответ 2

Мое решение состояло в том, чтобы установить возвращенную дату в 12:00 AM, поскольку NSDates работает в формате UTC

NSDate * adjustedDate = [[NSCalendar currentCalendar] dateBySettingHour:12 minute:0 second:0 ofDate:sender.date options:0];

Также для расчетов даты вы используете методы NSCalender, а не addTimeInterval

Ответ 3

Проверьте, используете ли вы неправильные символы форматирования большими буквами: "ГГГГ". Замените их "yyyy".

Ответ 4

Просто добавьте одну строку кода для установки часового пояса.

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

0 для GMT 00. Добавить в соответствии с вашим часовым поясом.

Ответ 5

Я столкнулся с той же проблемой, и вот что я получил:

Не используйте [описание даты], чтобы проверить NSDate, если вы хотите получить правильное представление для своей системы. Используйте NSDateFormatter, потому что он показывает дату на основе ваших системных настроек (в симуляторе это будут предпочтения симуляторов).

Например:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateStyle:NSDateFormatterShortStyle];
[df setTimeStyle:NSDateFormatterNoStyle];
NSLog(@"date for locale is %@", [df stringFromDate:date]);

Ответ 6

Возможно, из-за TimeZone...

Установите часовой пояс.

Ответ 7

Boolean futureevent;
- (void)viewDidLoad
{
 futureevent = false;
}

int intervall = (int) [currentdate timeIntervalSinceDate: datePicker.date] / 60;

if (intervall < 1200 && intervall > 0)
{
    futureevent = true;
    NSDate *newDate1 = [datePicker.date dateByAddingTimeInterval:60*60*24*1];
    birthdate = [newDate1.description substringToIndex:spaceRange.location];
}
else
{
    if (futureevent)
    {
        NSDate *newDate1 = [datePicker.date dateByAddingTimeInterval:60*60*24*1];
        birthdate = [newDate1.description substringToIndex:spaceRange.location];
    }
    else
    {
        birthdate = [datePicker.date.description substringToIndex:spaceRange.location];
    }
}

Ответ 8

Это не возвращает неправильную дату. В действительности, когда вы выбираете так называемую запрещенную дату, сборщик даты сбрасывается до максимально или минимально допустимой даты с первым моментом дня, то есть 12:00.

Поэтому, если вы находитесь в месте, где часовой пояс, например, на 2 часа опережает время по Гринвичу, дата, возвращаемая палитрой дат, будет вчера, в 22:00 по Гринвичу. Так что здесь вы можете подумать, что он возвращает вчерашнюю дату, но если вы конвертируете ее в свой часовой пояс, вы получите только сегодняшнюю дату, но компонент времени будет 12:00 AM.