web-dev-qa-db-fra.com

NSDate obtenir année / mois / jour

Comment puis-je obtenir l'année/mois/jour d'un objet NSDate sans autre information? Je me rends compte que je pourrais probablement faire cela avec quelque chose semblable à ceci:

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

Mais cela semble être un casse-tête pour quelque chose d'aussi simple que d'obtenir l'année/mois/jour d'un NSDate. N 'y a-t-il pas une autre solution?

287
Richard J. Ross III

Comme c'est apparemment ma réponse la plus populaire, je vais essayer de la modifier pour contenir un peu plus d'informations.

Malgré son nom, NSDate en lui-même marque simplement un point dans le temps de la machine, pas une date. Il n'y a pas de corrélation entre le moment spécifié par un NSDate et une année, un mois ou un jour. Pour cela, vous devez vous référer à un calendrier. Tout moment donné renverra des informations de date différentes en fonction du calendrier que vous regardez (les dates ne sont pas les mêmes dans les calendriers grégorien et juif, par exemple), et bien que le calendrier grégorien soit le calendrier le plus utilisé dans le monde. monde - je suppose - nous sommes un peu biaisés que NSDate devrait toujours l’utiliser. Heureusement, NSDate est beaucoup plus bipartisan.


Pour obtenir la date et l'heure, vous devrez passer par NSCalendar, comme vous l'avez mentionné, mais il existe un moyen plus simple de procéder:

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

Cela génère un objet NSDateComponents contenant le jour, le mois et l'année à partir du calendrier système actuel pour le jour actuel. ( Remarque: Ce n'est pas nécessairement le calendrier actuel spécifié par l'utilisateur, mais uniquement celui par défaut du système.)

Bien sûr, si vous utilisez un calendrier ou une date différente, vous pouvez facilement changer cela. Une liste des calendriers et des unités de calendrier disponibles est disponible dans le NSCalendar Référence de la classe . Plus d'informations sur NSDateComponents sont disponibles dans NSDateComponents Référence de la classe .


Pour référence, accéder à des composants individuels à partir de NSDateComponents est plutôt facile:

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

Attention: NSDateComponents ne contiendra aucune information valide pour les champs que vous demandez sauf si vous les avez générés avec cette information valide (c.-à-d. Demandez à NSCalendar de fournir cette information avec NSCalendarUnits ) NSDateComponents ne contient aucune information de référence en soi - ce ne sont que de simples structures contenant des chiffres auxquels vous pouvez accéder. Si vous voulez aussi avoir une époque, par exemple, sur NSDateComponents, vous devrez alimenter la méthode du générateur de NSCalendar avec le drapeau NSCalendarUnitEra.

610
Itai Ferber

Vous pouvez obtenir un composant distinct d'un NSDate à l'aide de 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]];

Si vous souhaitez obtenir le numéro du mois au lieu de l'abréviation, utilisez "MM". Si vous souhaitez obtenir des entiers, utilisez [myDayString intValue];

50
skocko76

Juste pour reformuler l'excellent code Itai (et fonctionnel!), Voici à quoi ressemblerait un exemple de classe d'assistance, pour renvoyer la valeur année d'une variable NSDate donnée.

Comme vous pouvez le constater, il est assez facile de modifier ce code pour obtenir le mois ou le jour.

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

(Je ne peux pas croire que nous devions écrire nos propres fonctions de date de base sur iOS comme cela, en 2013 ...)

Autre chose: n'utilisez jamais <et> pour comparer deux valeurs NSDate.

XCode acceptera volontiers un tel code (sans erreurs ni avertissements), mais ses résultats sont une loterie. Vous devez utilisez la fonction "comparer" pour comparer les dates NSD:

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

Dans 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)
14
NatashaTheRobot

J'écris cette réponse parce que c'est la seule approche qui ne vous restitue pas les options des variables NSDateComponent et/ou ne force pas le décompression de ces variables (également pour 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 version amusante

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)
11
Kevin

Nouveau dans iOS 8

ObjC

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

rapide

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)
8
Yuchen Zhong

Si vous ciblez iOS 8+, vous pouvez utiliser les nouvelles méthodes de commodité NSCalendar pour obtenir ce résultat dans un format plus concis.

Commencez par créer un NSCalendar et utilisez ce que NSDate est requis.

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

Vous pouvez extraire les composants individuellement 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, encore plus succinctement, utilisez les pointeurs NSInteger via getEra:year:month:day:fromDate:

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

Pour plus d'informations et d'exemples, consultez Manipulation de NSDate simplifiée sous iOS 8 . Avertissement, j'ai écrit le post.

4
Joe Masilotti

Depuis iOS 8.0 (et OS X 10), vous pouvez utiliser la méthode composant pour simplifier l'obtention d'un seul composant de date, comme suit:

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

Devrait rendre les choses plus simples et espérons que cela soit mis en œuvre efficacement.

4
Christopher King

Voici la solution dans 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) 
2
Nitin Nain

Si vous souhaitez obtenir les composants NSDate individuels de NSDate, vous avez certainement besoin de la solution proposée par Itai Ferber. Mais si vous voulez pour passer directement de NSDate à une chaîne NSString, vous pouvez utiliser NSDateFormatter .

2
gumbo

Essaye ça . . .

extrait de code:

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

Il donne l'année courante, le mois, la date

2
Yogeesh H T
    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);
2
Linh Nguyen

Essayez ce qui suit:

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

rapide

Un moyen plus simple d’obtenir des éléments de date sous forme de chaîne facultative.

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

Swift 2.x

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

Vous pouvez l'utiliser comme

NSDate().currentDateInDayMonthYear()

Sortie

6 March 2016
1
Alserda

je fais de cette façon ....

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);
0
Shaik Riyaz

Pour obtenir une chaîne lisible par l'homme (jour, mois, année), vous pouvez faire:

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