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

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

Календарные основы

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

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

Перечисление 3  , Создающее календарные объекты

NSCalendar *currentCalendar = [NSCalendar currentCalendar];
 
NSCalendar *japaneseCalendar = [[NSCalendar alloc]
                                initWithCalendarIdentifier:NSJapaneseCalendar];
 
NSCalendar *usersCalendar =
                      [[NSLocale currentLocale] objectForKey:NSLocaleCalendar];

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

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

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

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

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

Перечисление 4  , Создающее компонентный объект даты

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:6];
[components setMonth:5];
[components setYear:2004];
 
NSInteger weekday = [components weekday]; // Undefined (== NSUndefinedDateComponent)

Преобразование между датами и компонентами даты

Для разложения даты в составляющие компоненты Вы используете NSCalendar метод components:fromDate:. В дополнение к самой дате необходимо указать компоненты, которые будут возвращены в NSDateComponents объект. Для этого метод берет немного маски, составленной из Calendar Units константы. Нет никакой потребности больше указывать компоненты, чем те, которыми Вы интересуетесь. Перечисление 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 ноября 2010, Вы получаете 2010 в течение года и 7 в течение дня. Если Вы вместо этого хотите знать, какой день числа года это - Вы, может использовать ordinalityOfUnit:inUnit:forDate: метод NSCalendar класс.

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

Перечисление 6 показывает, как создать объект даты представлять (в Григорианском календаре) первый понедельник в мае 2008.

Перечисление 6  , Создающее дату из компонентов

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setWeekday:2]; // Monday
[components setWeekdayOrdinal:1]; // The first Monday in the month
[components setMonth:5]; // May
[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];

Обратите внимание на то, что birthday в этом экземпляре имеет значение по умолчанию в течение года, который в этом случае является 1 AD (хотя это не гарантируется всегда значению по умолчанию к 1 AD). Если Вы позже преобразовываете, это относится ко времени компонентов или использует 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