Календари, компоненты даты и календарные единицы

Cocoa

Объекты календаря инкапсулируют информацию о системах отсчета времени, в которых в начало, длина и подразделения года определены. Вы можете использовать объекты календаря для преобразования между компонентами абсолютного времени и даты, таких как годы, дни, минуты.

Основы календаря

NSCalendar обеспечивает реализацию различных календарей. Он предоставляет данные для различных календарей, в том числе буддийский, григорианский, еврейский, исламский и японский (поддерживается ли конкретный календарь, зависит от версии операционной системы, проверяется NSLocale классом, чтобы определить, какие поддерживаются на данный релиз). NSCalendar тесно связан с классом NSDateComponents, экземпляры, которого описывают составные элементы даты, необходимые для календарных расчетов.

Календари определяются константами в NSLocale. Вы сможете получить календарь для предпочитаемой локали пользователя, наиболее легко это реализовать с помощью метода currentCalendar класса NSCalendar, вы можете получить по умолчанию календарь с любым объектом NSLocale при помощи ключа NSLocaleCalendar. Вы также можете создать любой объект календаря, указав идентификатор для календаря, который вы хотите. В листинге 3 показано, как создать объект календаря для японского календаря и текущего пользователя.

Листинг 3 Создание объектов календаря

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

NSCalendar *japCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSJapaneseCalendar];

NSCalendar *usersCalendar = [[NSLocale currentLocale] objectForKey:NSLocaleCalendar];

Здесь usersCalendar и currentCalendar эквивалентны, хотя они и являются различными объектами.

Компоненты даты и единицы календаря

Вы представляете составные элементы даты, такие как год, день и час используя объект NSDateComponents. Объект NSDateComponents может содержать либо абсолютные величины либо количественные единицы (кол-во часов, минут, лет).

iOS Примечание: В iOS 4.0 и более поздних NSDateComponents объект может содержать календарь, часовой пояс, и объект даты. Это позволяет передовать и возвращать компоненты даты из метода и сохранять им свое значение.

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

Листинг 4 показывает, как можно создать объект компонентов даты, которые можно использовать для создания даты, где единица год = 2012, единица месяца 5 и единица дня 6 (по григорианскому календарю это является 6-м мая 2012 г.) . Вы также можете использовать его, чтобы добавить 2012 единиц года, 5 единиц месяца, и 6 единиц дня к существующей дате. Значение дня недели (weekday) не определено, поскольку оно не указано явно.

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:6];
[components setMonth:5];
[components setYear:2012];

NSInteger weekday = [components weekday]; // Undefined (== NSUndefinedDateComponent)

Конвертация между датами и компонентами даты

Для разложения даты на составные компоненты, можно использовать метод NSCalendar components:fromDate:. В дополнение к самой дате, необходимо указать компоненты, которые должны быть возвращены в объект NSDateComponents. Для этого метода требуется маска, состоящая из констант единиц календаря. Нет существенной необходимости указывать больше компонентов, чем те, в которых вы заинтересованы. Листинг 5 показывает, как вычислить сегодняшний день и день недели.

Листинг 5 Получение компонентов даты

NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *weekdayComponents =
          [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];

NSInteger day = [weekdayComponents day];

NSInteger weekday = [weekdayComponents weekday];

Это дает вам абсолютные компоненты для даты. Например, если вы запросите компоненты года и дня для даты 7 апреля 2012 года, Вы получите 2012 для года и 7 в качестве дня. Если же вы хотите знать, о числе дня в году это можно используя метод ordinalityOfUnit:inUnit:forDate: класса NSCalendar.

Кроме того, можно создать дату из компонентов. Вы можете настроить экземпляр NSDateComponents, указав компоненты даты, а затем использовать метод dateFromComponents: класса NSCalendar для создания соответствующего объекта даты. Вы можете предоставить столько компонентов, сколько вам нужно (или выбрать). При наличии неполной информации для расчета абсолютного времени, значения по умолчанию, как правило, такие как 0 и 1, но это выбор конкретного выбранного календаря. Если вы предоставляете противоречивую информацию, календарь проигнорирует один или нескольких параметров.

Листинг 6 показывает, как создать объект даты для представления (по григорианскому календарю) для первого понедельника мая 2008 года.

Листинг 6 Создание даты из компонентов

NSDateComponents *components = [[NSDateComponents alloc] init];

[components setWeekday:2]; // Понедельник (для английской локали, для русской необходимо задать 1)

[components setWeekdayOrdinal:1]; // Первый понедельник в месяце

[components setMonth:5]; // Май

[components setYear:2008]; // Год

NSCalendar *gregorian = [[NSCalendar alloc]
                         initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *date = [gregorian dateFromComponents:components];

Для того чтобы гарантировать правильное поведение, вы должны убедиться, что используемые компоненты имеют смысл для календаря. Указание "запредельных", компонент, таких как день со значением -6 или февраль с 30-м числом в григорианском календаре, произведут неопределенное поведение.

Вам может потребоваться создать объект даты без таких компонентов, как год, чтобы сохранить день рождения вашего друга, например. Хотя технически невозможно создать yearless дату, вы можете использовать компоненты даты для создания объекта даты без указания года, как показано в листинге 7.

Листинг 7 Создание yearless даты

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setMonth:11];
[components setDay:7];

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *birthday = [gregorian dateFromComponents:components];

Обратите внимание, что день рождения в этом случае имеет значение по умолчанию для года, который в данном случае составляет 1 AD (хотя это не гарантирует, что всегда по умолчанию в 1 г. н.э.). Если в дальнейшем преобразовать эту дату к компонентам, или использовать NSDateFormatter объект, чтобы отобразить его, убедитесь, что не использовать значение года. Вы можете использовать NSDateFormatter метод dateFormatFromTemplate:options:locale: для создания форматирования yearless даты настраивая на язык пользователей.

Преобразование из одного календаря в другой

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

Листинг 8 Преобразование компонент даты из одного календаря в другой

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]; // освобождаем объекты, если не используется авто сбор мусора
[gregorian release];

NSCalendar *hebrew = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar];

NSUInteger unitFlags = NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit;

NSDateComponents *components = [hebrew components:unitFlags fromDate:date];

NSInteger day = [components day]; // 15
NSInteger month = [components month]; // 9
NSInteger year = [components year]; // 5764
 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac