NSDate получить год/месяц/день

Как я могу получить год/месяц/день объекта NSDate, не учитывая никакой другой информации? Я понимаю, что я мог бы сделать это с чем-то похожим на это:

NSCalendar *cal = [[NSCalendar alloc] init];
NSDateComponents *components = [cal components:0 fromDate:date];
int year = [components year];
int month = [components month];
int day = [components day];

Но это, кажется, очень много хлопот для чего-то простого, как получение NSDate года/месяца/дня. Есть ли другое решение?

Ответ 1

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

Несмотря на свое название, NSDate сам по себе просто отмечает точку в машинное время, а не дату. Нет никакой корреляции между временем, указанным NSDate и годом, месяцем или днем. Для этого вам нужно обратиться к календарю. Любой данный момент времени будет возвращать другую информацию о дате в зависимости от того, какой календарь вы просматриваете (например, даты не совпадают как в григорианском, так и в еврейском календаре), а григорианский календарь - наиболее широко используемый календарь в мир - я предполагаю - мы немного предвзяты, что NSDate должен всегда использовать его. NSDate, к счастью, гораздо более двупартийный.


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

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

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

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


Для справки, доступ к отдельным компонентам из NSDateComponents довольно прост:

NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];

Вам просто нужно помнить: NSDateComponents не будет содержать достоверную информацию для любых полей, которые вы просите, если вы не сгенерировали их с этой достоверной информацией (т.е. запросить NSCalendar, чтобы предоставить эту информацию с помощью NSCalendarUnit s). NSDateComponents не содержат справочной информации сами по себе - это просто простые структуры, которые содержат номера для доступа. Если вы хотите также получить эру, например, из NSDateComponents, вам нужно будет подать метод генератора из NSCalendar с флагом NSCalendarUnitEra.

Ответ 2

Вы можете получить отдельный компонент NSDate, используя NSDateFormatter:

NSDateFormatter *df = [[NSDateFormatter alloc] init];

[df setDateFormat:@"dd"];
myDayString = [df stringFromDate:[NSDate date]];

[df setDateFormat:@"MMM"];
myMonthString = [df stringFromDate:[NSDate date]];

[df setDateFormat:@"yy"];
myYearString = [df stringFromDate:[NSDate date]];

Если вы хотите получить месяц вместо аббревиатуры, используйте "MM". Если вы хотите получить целые числа, используйте [myDayString intValue];

Ответ 3

Просто для того, чтобы переписать Itai превосходный (и рабочий!) код, вот как выглядит примерный вспомогательный класс, чтобы вернуть значение года данной переменной NSDate.

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

+(int)getYear:(NSDate*)date
{
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:date];

    int year = [components year];
    int month = [components month];
    int day = [components day];

    return year;
}

(Я не могу поверить, что нам нужно написать свои собственные основные функции даты iOS, подобные этому, в 2013 году...)

Еще одна вещь: никогда не используйте < и > для сравнения двух значений NSDate.

XCode с радостью примет такой код (без каких-либо ошибок или предупреждений), но его результаты - лотерея. Вы должны использовать функцию сравнения для сравнения NSDates:

if ([date1 compare:date2] == NSOrderedDescending) {
    // date1 is greater than date2        
}

Ответ 4

В Swift 2.0:

    let date = NSDate()
    let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
    let components = calendar.components([.Month, .Day], fromDate: date)

    let (month, day) = (components.month, components.day)

Ответ 5

Я пишу этот ответ, потому что это единственный подход, который не дает вам опций из переменных NSDateComponent и/или принудительно разворачивает эти переменные (также для Swift 3).

Swift 3

let date = Date()
let cal = Calendar.current
let year = cal.component(.year, from: date)
let month = cal.component(.month, from: date)
let day = cal.component(.day, from: date)

Swift 2

let date = NSDate()
let cal = NSCalendar.currentCalendar()
let year = cal.component(.Year, fromDate: date)
let month = cal.component(.Month, fromDate: date)
let day = cal.component(.Day, fromDate: date)

Бонус Swift 3 веселая версия

let date = Date()
let component = { (unit) in return Calendar.current().component(unit, from: date) }
let year = component(.year)
let month = component(.month)
let day = component(.day)

Ответ 6

Новое в iOS 8

ObjC

NSDate *date = [NSDate date];
NSInteger era, year, month, day;
[[NSCalendar currentCalendar] getEra:&era year:&year month:&month day:&day fromDate:date];

Swift

let date = NSDate.init()
var era = 0, year = 0, month = 0, day = 0
NSCalendar.currentCalendar().getEra(&era, year:&year, month:&month, day:&day, fromDate: date)

Ответ 7

Если вы ориентируетесь на iOS 8+, вы можете использовать новые методы NSCalendar для достижения этого в более сжатом формате.

Сначала создайте NSCalendar и используйте любое NSDate.

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [NSDate date];

Вы можете извлекать компоненты по отдельности через component:fromDate:

NSInteger year = [calendar component:NSCalendarUnitYear fromDate:date];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:date];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:date];

Или, еще более лаконично, используйте указатели NSInteger через getEra:year:month:day:fromDate:

NSInteger year, month, day;
[calendar getEra:nil year:&year month:&month day:&day fromDate:date];

Для получения дополнительной информации и примеров ознакомьтесь с NSDate Manipulation Made Easy в iOS 8. Отказ от ответственности, я написал сообщение.

Ответ 9

    NSDate *currDate = [NSDate date];
    NSCalendar*       calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents* components = [calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:currDate];
    NSInteger         day = [components day];
    NSInteger         month = [components month];
    NSInteger         year = [components year];
    NSLog(@"%d/%d/%d", day, month, year);

Ответ 10

Здесь решение в Swift:

let todayDate = NSDate()
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!

// Use a mask to extract the required components. Extract only the required components, since it'll be expensive to compute all available values.
let components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: todayDate)

var (year, month, date) = (components.year, components.month, components.day) 

Ответ 11

Как и в iOS 8.0 (и OS X 10), вы можете использовать метод компонент, чтобы упростить получение одного компонента даты следующим образом:

int year = [[NSCalendar currentCalendar] component:NSCalendarUnitYear fromDate:[NSDate date]];

Делайте вещи проще и, надеюсь, это эффективно реализовано.

Ответ 12

Попробуйте следующее:

    NSString *birthday = @"06/15/1977";
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM/dd/yyyy"];
    NSDate *date = [formatter dateFromString:birthday];
    if(date!=nil) {
        NSInteger age = [date timeIntervalSinceNow]/31556926;
        NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
        NSInteger day = [components day];
        NSInteger month = [components month];
        NSInteger year = [components year];

        NSLog(@"Day:%d Month:%d Year:%d Age:%d",day,month,year,age);
    }
    [formatter release];

Ответ 13

Попробуйте это.,.

Фрагмент кода:

 NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
 int year = [components year];
 int month = [components month];
 int day = [components day];

Он показывает текущий год, месяц, дату

Ответ 14

Swift 2.x

extension NSDate {
    func currentDateInDayMonthYear() -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "d LLLL yyyy"
        return dateFormatter.stringFromDate(self)
    }
}

Вы можете использовать его как

NSDate().currentDateInDayMonthYear()

Выход

6 March 2016

Ответ 15

Я делаю так....

NSDate * mydate = [NSDate date];

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

NSCalendarUnit units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;

NSDateComponents * myComponents  = [mycalendar components:units fromDate:mydate];

NSLog(@"%d-%d-%d",myComponents.day,myComponents.month,myComponents.year);

Ответ 16

Чтобы получить удобочитаемую строку (день, месяц, год), вы можете:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [dateFormatter stringFromDate:dateEndDate];

Ответ 17

Swift

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

extension Date {

  // Year 
  var currentYear: String? {
    return getDateComponent(dateFormat: "yy")
    //return getDateComponent(dateFormat: "yyyy")
  }

  // Month 
  var currentMonth: String? {
    return getDateComponent(dateFormat: "M")
    //return getDateComponent(dateFormat: "MM")
    //return getDateComponent(dateFormat: "MMM")
    //return getDateComponent(dateFormat: "MMMM")
  }


  // Day
  var currentDay: String? {
    return getDateComponent(dateFormat: "dd")
    //return getDateComponent(dateFormat: "d")
  }


  func getDateComponent(dateFormat: String) -> String? {
    let format = DateFormatter()
    format.dateFormat = dateFormat
    return format.string(from: self)
  }


}

let today = Date()
print("Current Year - \(today.currentYear)")  // result Current Year - Optional("2017")
print("Current Month - \(today.currentMonth)")  // result Current Month - Optional("7")
print("Current Day - \(today.currentDay)")  // result Current Day - Optional("10")