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:)).
NSDate
como en Objective-C?Respuestas:
Swift tiene su propio
Date
tipo. 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
Date
estructura . 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 usarDateComponents
para especificar los componentes y luegoCalendar
crear la fecha. ElCalendar
da elDate
contexto. 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
DateFormatter
soporta.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
NSDate
clase 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
NSDate
esta manera.Tenga en cuenta también que esta implementación simplemente se bloqueará si intenta inicializar
NSDate
pasando una cadena que no se puede analizar correctamente. Esto se debe al desenvolvimiento forzado del valor opcional devuelto pordateFromString
. Si desea devolvernil
un 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
NSDateFormatter
cada 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 lasNSDate
extensiones.Swift no tiene su propio tipo de fecha, pero puede usar el
NSDate
tipo de cacao existente , por ejemplo:Que puedes usar como:
fuente
NSDateFormatter
mé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
dateComponents
De 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
swift3
sintaxis.No uso el
parse
mé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