Pregunta

¿Cómo puedo obtener el año / mes / día de un objeto NSDate, dado ninguna otra información? Soy consciente de que probablemente podría hacer esto con algo similar a esto:

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

Pero eso parece ser todo un montón de problemas para algo tan simple como conseguir año / mes / día de un NSDate. ¿Hay alguna otra solución?

¿Fue útil?

Solución

Debido a que este es aparentemente mi respuesta más popular, voy a tratar de editar para que contenga un poco más de información.

A pesar de su nombre, NSDate en sí mismo simplemente marca un punto en el tiempo de la máquina, no una fecha. No hay correlación entre el punto en el tiempo especificado por un NSDate y un año, mes o día. Por eso, hay que hacer referencia a un calendario. Cualquier punto dado en el tiempo volverá diferente información de fecha del calendario en base a lo que está viendo (fechas no son los mismos en ambos los calendarios gregorianos y judíos, por ejemplo), y si bien el calendario gregoriano es el calendario más utilizado en el mundo - Asumo - estamos un poco parcial que NSDate debería utilizar siempre la misma. NSDate, por suerte, es mucho más bipartidista.


fecha y hora Conseguir va a tener que pasar a través de NSCalendar, como usted ha mencionado, pero hay una manera más sencilla de hacerlo:

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

Esto genera un objeto que contiene NSDateComponents el día, el mes y el año del calendario actual del sistema para el día actual. ( Nota:. esto no es necesariamente la corriente especificado por el usuario calendario, sólo el sistema por defecto)

Por supuesto, si usted está usando un calendario o fecha diferente, se puede cambiar fácilmente eso. Una lista de los calendarios disponibles y las unidades de calendario se puede encontrar en el NSCalendar Referencia de la Clase . Más información sobre NSDateComponents se puede encontrar en el NSDateComponents Referencia de la Clase .


Para referencia, el acceso a los componentes individuales de la NSDateComponents es bastante fácil:

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

Sólo hay que tener en cuenta: NSDateComponents no contendrá información válida para cualquier campo que usted pide menos que las generó con esa información válida (es decir petición NSCalendar para proporcionar esa información con NSCalendarUnits). NSDateComponents no contienen información de referencia en sí mismos - son sólo simples estructuras que sujetan los números para que usted pueda acceder. Si desea obtener también una época, por ejemplo, de NSDateComponents, que tendrá que alimentar el método generador de NSCalendar con la bandera NSCalendarUnitEra.

Otros consejos

Se puede obtener un componente separado del 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]];

Si desea obtener el número del mes en lugar de abreviatura, el uso de "MM". Si desea obtener números enteros, el uso [myDayString intValue];

Sólo para reformular excelente de Itai (y trabajando!) De código, esto es lo que muestra una clase de ayuda se vería así, devolver el año valor de una variable dada NSDate.

Como se puede ver, es bastante fácil de modificar este código para obtener el mes o el día.

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

(no puedo creer que vayamos a tener que escribir nuestras propias funciones básicas fecha iOS como éste, en 2013 ...)

Otra cosa:. Nunca utilice para comparar dos valores NSDate

XCode aceptará sin problemas dicho código (sin ningún tipo de error o advertencia), pero sus resultados son una lotería. Usted debe utilizar la función "Comparar" compara NSDates:

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

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

Estoy escribiendo esta respuesta porque es el único enfoque que no le da la espalda a partir de variables opcionales NSDateComponent y / o de fuerza desenvolver aquellas variables (también para 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)

Bono Swift versión 3 de la diversión

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)

Nuevo en 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)

Si el idioma de iOS 8+ puede utilizar los nuevos métodos NSCalendar conveniencia de lograr esto en un formato más conciso.

En primer lugar crear un NSCalendar y utilizar cualquier NSDate se requiere.

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

Se podría extraer componentes de forma individual a través de component:fromDate:

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

O, aún más sucintamente, los punteros uso NSInteger vía getEra:year:month:day:fromDate:

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

Para obtener más información y ejemplos echa un vistazo a NSDate hizo fácil manipulación en IOS 8 . Descargo de responsabilidad, escribí el mensaje.

A partir de iOS 8.0 (y OS X 10) se puede utilizar el componente método para simplificar la obtención de un único componente de la fecha de este modo:

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

En caso de simplificar las cosas y espero que esto está implementado de manera eficiente.

Si desea obtener los NSDateComponents individuales de NSDate, que sin duda necesita la solución sugerida por Itai Ferber. Pero si quieres pasar de NSDate directamente a un NSString, puede utilizar 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);

Aquí está la solución en 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) 

Probar. . .

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

Da año, el mes, la fecha

Trate lo siguiente:

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

Se puede utilizar como

NSDate().currentDateInDayMonthYear()

salida

6 March 2016

Swift

manera más fácil de conseguir cualquier elemento de la fecha como una cadena 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")

lo hago de esta manera ....

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 llegar cadena legible por humanos (día, mes, año), puede hacerlo:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [dateFormatter stringFromDate:dateEndDate];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top