Swift tiene su propio Datetipo. No es necesario usar NSDate.
Crear una fecha y hora en Swift
En Swift, las fechas y horas se almacenan en un número de coma flotante de 64 bits que mide la cantidad de segundos desde la fecha de referencia del 1 de enero de 2001 a las 00:00:00 UTC . Esto se expresa en la Dateestructura . Lo siguiente le daría la fecha y hora actuales:
let currentDateTime =Date()
Para crear otras fechas y horas, puede usar uno de los siguientes métodos.
Método 1
Si conoce el número de segundos antes o después de la fecha de referencia de 2001, puede usar eso.
let someDateTime =Date(timeIntervalSinceReferenceDate:-123456789.0)//Feb2,1997,10:26 AM
Método 2
Por supuesto, sería más fácil usar cosas como años, meses, días y horas (en lugar de segundos relativos) para hacer un Date. Para esto, puede usar DateComponentspara especificar los componentes y luego Calendarcrear la fecha. El Calendarda el Datecontexto. De lo contrario, ¿cómo sabría en qué zona horaria o calendario expresarlo?
// Specify date components
var dateComponents =DateComponents()
dateComponents.year =1980
dateComponents.month =7
dateComponents.day =11
dateComponents.timeZone =TimeZone(abbreviation:"JST")// Japan Standard Time
dateComponents.hour =8
dateComponents.minute =34// Create date from components
let userCalendar =Calendar.current // user calendar
let someDateTime = userCalendar.date(from: dateComponents)
Se pueden encontrar otras abreviaturas de zona horaria Aquí . Si lo deja en blanco, el valor predeterminado es usar la zona horaria del usuario.
Método 3
La forma más sucinta (pero no necesariamente la mejor) podría ser usar DateFormatter.
let formatter =DateFormatter()
formatter.dateFormat ="yyyy/MM/dd HH:mm"let someDateTime = formatter.date(from:"2016/10/08 22:31")
Esto se hace mejor usando una extensión de la NSDateclase existente .
La siguiente extensión agrega un nuevo inicializador que creará una fecha en el entorno local actual utilizando la cadena de fecha en el formato que especificó.
Ahora puede crear un NSDate de Swift simplemente haciendo:
NSDate(dateString:"2014-06-06")
Tenga en cuenta que esta implementación no almacena en caché el NSDateFormatter, que es posible que desee hacer por razones de rendimiento si espera crear muchos correos electrónicos de NSDateesta manera.
Tenga en cuenta también que esta implementación simplemente se bloqueará si intenta inicializar NSDatepasando una cadena que no se puede analizar correctamente. Esto se debe al desenvolvimiento forzado del valor opcional devuelto por dateFromString. Si desea devolver nilun análisis incorrecto, lo ideal sería utilizar un inicializador defectuoso; pero no puede hacerlo ahora (junio de 2015), debido a una limitación en Swift 1.2, por lo que su siguiente mejor opción es usar un método de fábrica de clase.
Entonces, ¿cuál es la palabra "conveniencia" hacer aquí?
James Burns
18
Indica que la extensión proporciona un inicializador que de hecho delega la inicialización a un inicializador designado ya existente, que en este caso es el inicializador NSDate.init (timeInterval:, sinceDate :). Esto se describe en la página 275 del libro The Swift Programming Language.
algal
1
Una falla que veo en el código anterior es volver a crear NSDateFormattercada vez que se accede a la función. Como indica la Guía de formato de fecha , la creación de un formateador de fecha no es una operación barata . Además, la clase es segura para subprocesos desde iOS7, por lo que se puede usar con seguridad para todas las NSDateextensiones.
Yevhen Dubinin
@eugenedubinin correcto. Es por eso que dije "esta implementación no almacena en caché el NSDateFormatter, que es posible que desee hacer por razones de rendimiento".
Swift no tiene su propio tipo de fecha, pero puede usar el NSDatetipo de cacao existente , por ejemplo:
classDate{classfunc from(year:Int, month:Int, day:Int)->Date{let gregorianCalendar =NSCalendar(calendarIdentifier:.gregorian)!var dateComponents =DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
let date = gregorianCalendar.date(from: dateComponents)!return date
}classfunc parse(_ string:String, format:String="yyyy-MM-dd")->Date{let dateFormatter =DateFormatter()
dateFormatter.timeZone =NSTimeZone.default
dateFormatter.dateFormat = format
let date = dateFormatter.date(from: string)!return date
}}
Que puedes usar como:
var date =Date.parse("2014-05-20")var date =Date.from(year:2014, month:05, day:20)
Tuve que cambiar la línea: var date = gregorian? .DateFromComponents (c) pero no entiendo por qué, y el análisis return dateFmt.dateFromString también se queja. ¿Alguna pista? Ah, ¿he cambiado el tipo de retorno de la función de NSDate a NSDate? lo que le permite compilar. Pero no estoy seguro de por qué necesita ser anulable.
El senador
1
@TheSenator NSCalendar init devuelve un opcional (?) Por lo que gregorian es opcional (?). Acceder a una necesidad opcional de encadenamiento opcional para acceder a él de manera gregorian? .DateFromCoomponents es el encadenamiento opcional para desenvolver el valor de las opciones gregorian (NSCalendar). Más para encadenamiento opcional aquí
iluvatar_GR
NSGregorianCalendar está en desuso a partir de iOS 8, así que use NSCalendarIdentifierGregorian en su lugar
Adam Knights
2
@El senador se queja porque Swift tiene estructura de fecha, y este código vuelve a declarar la fecha nuevamente como clase. Entonces deberías hacer algo como: 'fecha de extensión' y 'función estática'
Zaporozhchenko Oleksandr
Una nota sobre la secuencia de análisis de nuevo a la fecha. Una cadena "1979-07-01" con "aaaa-MM-dd" para el NSDateFormattermétodo date(from:). Vuelve nil. Encontré este problema en el registro de fallas de fabric.io.
AechoLiu
12
Así es como lo hice en Swift 4.2:
extensionDate{/// Create a date from specified parameters
///
/// - Parameters:
/// - year: The desired year
/// - month: The desired month
/// - day: The desired day
/// - Returns: A `Date` object
staticfunc from(year:Int, month:Int, day:Int)->Date?{let calendar =Calendar(identifier:.gregorian)var dateComponents =DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
return calendar.date(from: dateComponents)??nil}}
Uso:
let marsOpportunityLaunchDate =Date.from(year:2003, month:07, day:07)
Crear un formateador de fecha no es una operación barata. Si es probable que use un formateador con frecuencia, generalmente es más eficiente almacenar en caché una sola instancia que crear y eliminar múltiples instancias. Un enfoque es usar una variable estática
Y si bien estoy de acuerdo con @Leon en que este debería ser un inicializador de error, cuando ingresas datos iniciales, podríamos tener uno que no esté disponible (tal como lo hay UIImage(imageLiteralResourceName:)).
NSDatecomo en Objective-C?Respuestas:
Swift tiene su propio
Datetipo. No es necesario usarNSDate.Crear una fecha y hora en Swift
En Swift, las fechas y horas se almacenan en un número de coma flotante de 64 bits que mide la cantidad de segundos desde la fecha de referencia del 1 de enero de 2001 a las 00:00:00 UTC . Esto se expresa en la
Dateestructura . Lo siguiente le daría la fecha y hora actuales:Para crear otras fechas y horas, puede usar uno de los siguientes métodos.
Método 1
Si conoce el número de segundos antes o después de la fecha de referencia de 2001, puede usar eso.
Método 2
Por supuesto, sería más fácil usar cosas como años, meses, días y horas (en lugar de segundos relativos) para hacer un
Date. Para esto, puede usarDateComponentspara especificar los componentes y luegoCalendarcrear la fecha. ElCalendarda elDatecontexto. De lo contrario, ¿cómo sabría en qué zona horaria o calendario expresarlo?Se pueden encontrar otras abreviaturas de zona horaria Aquí . Si lo deja en blanco, el valor predeterminado es usar la zona horaria del usuario.
Método 3
La forma más sucinta (pero no necesariamente la mejor) podría ser usar
DateFormatter.Los estándares técnicos Unicode muestran otros formatos que
DateFormattersoporta.Notas
Vea mi respuesta completa sobre cómo mostrar la fecha y la hora en un formato legible. Lea también estos excelentes artículos:
fuente
Esto se hace mejor usando una extensión de la
NSDateclase existente .La siguiente extensión agrega un nuevo inicializador que creará una fecha en el entorno local actual utilizando la cadena de fecha en el formato que especificó.
Ahora puede crear un NSDate de Swift simplemente haciendo:
Tenga en cuenta que esta implementación no almacena en caché el NSDateFormatter, que es posible que desee hacer por razones de rendimiento si espera crear muchos correos electrónicos de
NSDateesta manera.Tenga en cuenta también que esta implementación simplemente se bloqueará si intenta inicializar
NSDatepasando una cadena que no se puede analizar correctamente. Esto se debe al desenvolvimiento forzado del valor opcional devuelto pordateFromString. Si desea devolvernilun análisis incorrecto, lo ideal sería utilizar un inicializador defectuoso; pero no puede hacerlo ahora (junio de 2015), debido a una limitación en Swift 1.2, por lo que su siguiente mejor opción es usar un método de fábrica de clase.Un ejemplo más elaborado, que aborda ambos problemas, está aquí: https://gist.github.com/algal/09b08515460b7bd229fa .
Actualización para Swift 5
fuente
NSDateFormattercada vez que se accede a la función. Como indica la Guía de formato de fecha , la creación de un formateador de fecha no es una operación barata . Además, la clase es segura para subprocesos desde iOS7, por lo que se puede usar con seguridad para todas lasNSDateextensiones.Swift no tiene su propio tipo de fecha, pero puede usar el
NSDatetipo de cacao existente , por ejemplo:Que puedes usar como:
fuente
NSDateFormattermétododate(from:). Vuelvenil. Encontré este problema en el registro de fallas de fabric.io.Así es como lo hice en Swift 4.2:
Uso:
fuente
dateComponentsDe acuerdo con la documentación de Apple
Ejemplo:
fuente
En Swift 3.0, ha establecido el objeto de fecha de esta manera.
fuente
Personalmente, creo que debería ser un inicializador fallable:
De lo contrario, una cadena con un formato no válido generará una excepción.
fuente
Según la respuesta de @mythz, decido publicar una versión actualizada de su extensión usando la
swift3sintaxis.No uso el
parsemétodo, pero si alguien lo necesita, actualizaré esta publicación.fuente
A menudo tengo la necesidad de combinar valores de fecha de un lugar con valores de tiempo para otro. Escribí una función auxiliar para lograr esto.
fuente
De acuerdo con la Guía de formato de datos de Apple
Y si bien estoy de acuerdo con @Leon en que este debería ser un inicializador de error, cuando ingresas datos iniciales, podríamos tener uno que no esté disponible (tal como lo hay
UIImage(imageLiteralResourceName:)).Así que aquí está mi enfoque:
Y ahora disfruta simplemente llamando:
fuente