NSDate obter ano / mês / dia

Como posso obter o ano / mês / dia de um object NSDate , sem outras informações? Eu percebo que eu provavelmente poderia fazer isso com algo semelhante a isso:

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

Mas isso parece ser um monte de problemas para algo tão simples como conseguir um ano / mês / dia da NSDate . existe alguma outra solução?

Porque esta é aparentemente a minha resposta mais popular, vou tentar editá-la para conter um pouco mais de informação.

Apesar de seu nome, a NSDate simplesmente marca um ponto no tempo da máquina, não uma data. Não há correlação entre o ponto no tempo especificado por um NSDate e um ano, mês ou dia. Para isso, você deve se referir a um calendar. Qualquer ponto no tempo retornará informações de data diferentes com base em qual calendar você está olhando (as datas não são as mesmas nos calendars gregoriano e judaico, por exemplo), e enquanto o calendar gregoriano é o calendar mais usado no calendar mundo – estou assumindo – estamos um pouco tendenciosos que NSDate sempre deve usá-lo. NSDate , por sorte, é bem mais bipartidária.


Obter data e hora terá que passar pelo NSCalendar , como você mencionou, mas há uma maneira mais simples de fazer isso:

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

Isso gera um object NSDateComponents contendo o dia, mês e ano do calendar atual do sistema para o dia atual. ( Nota: isso não é necessariamente o calendar atual especificado pelo usuário , apenas o padrão do sistema).

Claro, se você estiver usando um calendar ou data diferente, você pode facilmente mudar isso. Uma lista de calendars e unidades de calendar disponíveis pode ser encontrada na Referência de Classe NSCalendar . Mais informações sobre o NSDateComponents podem ser encontradas na Referência da Classe NSDateComponents .


Para referência, acessar componentes individuais do NSDateComponents é bastante fácil:

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

Você só precisa ficar atento: NSDateComponents não conterá informações válidas para nenhum campo que você solicitar, a menos que você as tenha gerado com essas informações válidas (ou seja, solicite o NSCalendar para fornecer essas informações com NSCalendarUnit s). NSDateComponents não contêm nenhuma informação de referência em si – são apenas estruturas simples que contêm números para você acessar. Se você quiser também obter uma era, por exemplo, fora do NSDateComponents , você terá que alimentar o método gerador do NSCalendar com o sinalizador NSCalendarUnitEra .

Você pode obter um componente separado de um NSDate usando 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]]; 

Se você deseja obter o número do mês em vez da abreviação, use “MM”. Se você deseja obter inteiros, use [myDayString intValue];

Apenas para reformular o excelente (e funcional!) Código de Itai, aqui está como seria uma class auxiliar de exemplo, para retornar o valor de ano de uma dada variável NSDate.

Como você pode ver, é fácil modificar esse código para obter o mês ou o dia.

 +(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; } 

(Eu não posso acreditar que estamos tendo que escrever nossas próprias funções básicas de data do iOS assim, em 2013 …)

Uma outra coisa: nunca use para comparar dois valores NSDate.

O XCode aceitará com prazer esse código (sem erros ou avisos), mas seus resultados são uma loteria. Você deve usar a function “compare” para comparar NSDates:

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

No 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) 

Eu estou escrevendo esta resposta porque é a única abordagem que não lhe dá opções de volta de variables NSDateComponent e / ou força a desembrulhar essas variables ​​(também para o 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) 

Bonus Swift 3 versão divertida

 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) 

Novo no iOS 8

ObjC

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

Rápido

 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) 

Se você estiver segmentando o iOS 8+, poderá usar os novos methods convenientes do NSCalendar para conseguir isso em um formato mais conciso.

Primeiro crie um NSCalendar e use qualquer NSDate necessário.

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

Você pode extrair componentes individualmente via component:fromDate:

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

Ou, ainda mais sucintamente, use pointers getEra:year:month:day:fromDate: via getEra:year:month:day:fromDate:

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

Para obter mais informações e exemplos, confira a Manipulação do NSDate facilitada no iOS 8 . Disclaimer, eu escrevi o post.

A partir do iOS 8.0 (e OS X 10), você pode usar o método component para simplificar a obtenção de um único componente de data da seguinte forma:

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

Deve tornar as coisas mais simples e esperamos que isso seja implementado de forma eficiente.

Se você deseja obter os NSDateComponents individuais da NSDate, você definitivamente precisará da solução sugerida por Itai Ferber. Mas se você quiser ir do NSDate diretamente para um NSString, você pode usar o NSDateFormatter .

  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); 

Aqui está a solução no 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) 

Tente o seguinte:

  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]; 

Swift 2.x

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

Você pode usá-lo como

 NSDate().currentDateInDayMonthYear() 

Saída

 6 March 2016 

Tente isso. . .

Fragmento de código:

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

Dá ano atual, mês, data

eu faço desta maneira ….

 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); 

Para obter uma string legível (dia, mês, ano), você pode fazer:

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

Rápido

Maneira mais fácil de obter quaisquer elementos de data como uma String opcional.

 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")