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