Как хранить даты без времени в Core Data - PullRequest
8 голосов
/ 05 августа 2009

Я пытался найти разумный способ хранения ежедневных данных с использованием Core Data на iPhone.

Мое приложение получает данные в формате csv с датой, но без времени:

date, cycles
2009-08-01, 123
2009-08-02, 234
2009-08-03, 345
2009-08-04, 456

Когда эти данные сохраняются, в день должна быть только одна запись. Я решил, что лучше всего создать NSDate для хранения, но удалить данные о часовом и часовом поясе.

Я могу легко создать NSDate без часов, минут или секунд, используя либо NSDateComponents, либо NSDateFormatter. Однако даже когда я явно устанавливаю часовой пояс на UTC или на ноль секунд от GMT, при выводе созданной даты с помощью NSLog () всегда мой местный часовой пояс будет выглядеть следующим образом:

2009-07-29 00:00:00 +0100

Кто-нибудь знает лучший способ сделать NSDates без временных компонентов? Или, возможно, лучший способ хранения дат?

Ответы [ 3 ]

9 голосов
/ 05 августа 2009

Хорошее практическое правило программирования - всегда хранить даты в UTC. Неважно, используете ли вы Core Data или нет; вам все равно придется проделать некоторую работу, потому что классы свиданий Apple в значительной степени отстой.

Даты представляются внутри в виде количества секунд с контрольной даты, которая, я полагаю, 1 января 2001 года 00:00:00 (хотя фактическая контрольная дата не очень важна). Дело в том, что NSDate объекты всегда изначально в UTC. Если даты, которые вы получаете в своем CSV-файле, являются локальными, вам нужно сделать что-то вроде этого, чтобы получить время UTC:

NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]];

Тогда я бы установил время на 00:00:00. Теперь вы сохраняете дату в полночь в UTC. Для целей презентации вы будете использовать NSDateFormatter, настроенный с выбранным вами часовым поясом (системный часовой пояс используется по умолчанию, если вы его не указали) для отображения этих дат.

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

Если вам не нравится это решение, вы всегда можете сохранить свои даты в альтернативном формате. Вы можете использовать double или int для хранения даты в каком-либо пользовательском формате (например, количество дней с некоторой контрольной даты), или вы даже можете свернуть свой собственный класс, чтобы смоделировать дату точно так, как вы хотите, и сохранить это как NSData объект. Пока класс реализует NSCoding, вы можете сериализовать его в объект NSData в Core Data. Вам просто нужно установить тип атрибута в Базовых данных на «Трансформируемый».

У вас есть множество вариантов, и ни один из них не требует написания ваших собственных запросов и баз данных SQLite.

3 голосов
/ 05 августа 2009

NSDate не имеет часового пояса. NSLog использует ваш местный часовой пояс; там написано +0100, потому что ты там.

2 голосов
/ 05 августа 2009

NSDate-объект всегда будет включать дату времени - чтобы процитировать документы, которые он "представляет [s] один момент времени", и делает это путем сохранения значения времени с его ссылочной даты (начало 1 января 2001 года в GMT, снова в соответствии с документами). Поэтому у вас не может быть NSDate, который не знает времени суток.

Вместо того, чтобы пытаться хранить даты по-своему, я все равно использовал бы NSDate в вашей модели и рассмотрел бы добавление пары методов в ваш класс сущностей, один из которых будет делать то, что вы описали выше, устанавливая NSDate в 00:00. : 00 в данный день. Другой может вернуть только дату из NSDate в вашем предпочтительном формате. Затем они будут использовать сгенерированные Core Data методы получения и установки для доступа к свойству NSDate.

Продолжая использовать NSDate, вы используете класс, с которым Core Data может работать изначально, а это означает, что вы все равно можете легко использовать предикаты для фильтрации или сортировать полученные результаты по дате, не задумываясь об этом.

...