Domanda

Come posso ottenere l'anno / mese / giorno di un oggetto NSDate, dato alcuna altra informazione? Mi rendo conto che probabilmente potrei farlo con qualcosa di simile a questo:

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

Ma che sembra essere un sacco di problemi per qualcosa di semplice come ottenere un NSDate anno / mese / giorno. C'è qualche altra soluzione?

È stato utile?

Soluzione

Perché questo è apparentemente la mia risposta più popolare, cercherò di modificarla per contenere un po 'di più informazioni.

Nonostante il nome, NSDate in sé e per sé semplicemente segna un punto nel tempo macchina, non è una data. Non c'è alcuna correlazione tra il punto nel tempo specificato da un NSDate e un anno, mese o giorno. Per questo, si deve fare riferimento a un calendario. Qualsiasi dato momento tornerà diversa informazioni aggiornate sulla base di quello del calendario che stai guardando (non sono gli stessi in entrambi i calendari gregoriani ed ebrei date, per esempio), e mentre il calendario gregoriano è il calendario più usato nel mondo - sto assumendo - siamo un po 'prevenuto che NSDate devono sempre usarlo. NSDate, per fortuna, è molto più bipartisan.


data e ora ottenere sta per passare attraverso NSCalendar, come lei ha ricordato, ma c'è un modo più semplice per farlo:

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

che genera un oggetto NSDateComponents contenente il giorno, il mese e l'anno dal calendario attuale sistema per il giorno corrente. ( Nota. questo non è necessariamente l'attuale specificato dall'utente calendario, solo il sistema di default)

Naturalmente, se si sta utilizzando un calendario o una data diversa, si può facilmente cambiare la situazione. Un elenco di calendari disponibili e le unità di calendario possono essere trovate nel NSCalendar Class Reference . Maggiori informazioni su NSDateComponents può essere trovato nel NSDateComponents Class Reference .


Per riferimento, accedendo singoli componenti dal NSDateComponents è piuttosto facile:

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

Devi solo essere consapevoli: NSDateComponents non conterrà informazioni valide per tutti i campi si chiede perché se non li hanno generati con quelle informazioni valide (cioè richiesta NSCalendar di fornire tali informazioni con NSCalendarUnits). NSDateComponents non contengono informazioni di riferimento in sé e per sé - sono solo semplici strutture che contengono i numeri per poter accedere. Se si desidera ottenere anche un'epoca, per esempio, di NSDateComponents, dovrete alimentare il metodo di generatore dal NSCalendar con la bandiera NSCalendarUnitEra.

Altri suggerimenti

È possibile ottenere componente separata di un NSDate utilizzando 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 si desidera ottenere il numero del mese invece di sigla, l'uso "MM". Se si desidera ottenere numeri interi, l'uso [myDayString intValue];

Solo per riformulare eccellente di Itai (e di lavoro!) Del codice, ecco quello che una classe di supporto del campione sarà simile, per restituire la anno valore di una data variabile NSDate.

Come si può vedere, è abbastanza facile da modificare il codice per ottenere il mese o il giorno.

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

(Non posso credere che stiamo avendo a scrivere i nostri propri di base funzioni di data iOS come questo, nel 2013 ...)

Un altra cosa:. Non bisogna mai usare per confrontare due valori NSDate

XCode sarà lieto di accettare tale codice (senza errori o avvisi), ma i suoi risultati sono una lotteria. È deve usare la funzione "Confronta" per confrontare NSDates:

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

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

Sto scrivendo questa risposta perché è l'unico approccio che non darvi optionals indietro dalle variabili NSDateComponent e / o forza scartare quelle variabili (anche per 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 versione 3 divertimento

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)

Novità 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)

Se si prendono di mira iOS 8+ è possibile utilizzare i nuovi metodi NSCalendar convenienza per raggiungere questo obiettivo in un formato più concisa.

Per prima cosa creare un NSCalendar e l'uso tutto ciò che è necessario NSDate.

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

Si potrebbe estrarre componenti singolarmente tramite component:fromDate:

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

Oppure, ancora più succintamente, puntatori uso NSInteger via getEra:year:month:day:fromDate:

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

Per ulteriori informazioni ed esempi check out NSDate manipolazione Made Easy in iOS 8 . Responsabilità, ho scritto il post.

A partire da iOS 8.0 (e OS X 10) è possibile utilizzare il componente metodo per semplificare ottenere un singolo componente di data in questo modo:

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

Dovrebbe rendere le cose più semplici e spero che questo sia implementato in modo efficiente.

Se si desidera ottenere i singoli NSDateComponents da NSDate, si sarebbe sicuramente bisogno di una soluzione suggerita da Itai Ferber. Ma se si vuole andare da NSDate direttamente ad un NSString, è possibile utilizzare 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);

Ecco la soluzione a 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) 

Prova questo. . .

Snippet di codice:

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

Si dà corrente anno, il mese, la data

Prova il seguente:

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

È possibile utilizzarlo come

NSDate().currentDateInDayMonthYear()

Output

6 March 2016

Swift

modo più facile per ottenere tutti gli elementi di data come una stringa opzionale.

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

faccio in questo modo ....

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

Per ottenere stringa leggibile (giorno, mese, anno), si può fare:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [dateFormatter stringFromDate:dateEndDate];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top