¿Cómo se crea un objeto de fecha a partir de una fecha en xcode rápido?
por ejemplo, en javascript harías:
var day = new Date('2014-05-20');
¿Cómo se crea un objeto de fecha a partir de una fecha en xcode rápido?
por ejemplo, en javascript harías:
var day = new Date('2014-05-20');
Respuestas:
Swift tiene su propio Date
tipo. No es necesario usar NSDate
.
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:
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) // Feb 2, 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 DateComponents
para especificar los componentes y luego Calendar
crear la fecha. El Calendar
da el Date
contexto. 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")
Los estándares técnicos Unicode muestran otros formatos queDateFormatter
soporta.
Vea mi respuesta completa sobre cómo mostrar la fecha y la hora en un formato legible. Lea también estos excelentes artículos:
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ó.
extension NSDate
{
convenience
init(dateString:String) {
let dateStringFormatter = NSDateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
let d = dateStringFormatter.dateFromString(dateString)!
self.init(timeInterval:0, sinceDate:d)
}
}
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 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 por dateFromString
. Si desea devolver nil
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 .
extension Date {
init(_ dateString:String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
let date = dateStringFormatter.date(from: dateString)!
self.init(timeInterval:0, since:date)
}
}
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 las NSDate
extensiones.
Swift no tiene su propio tipo de fecha, pero puede usar el NSDate
tipo de cacao existente , por ejemplo:
class Date {
class func 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
}
class func 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)
NSDateFormatter
método date(from:)
. Vuelve nil
. Encontré este problema en el registro de fallas de fabric.io.
Así es como lo hice en Swift 4.2:
extension Date {
/// Create a date from specified parameters
///
/// - Parameters:
/// - year: The desired year
/// - month: The desired month
/// - day: The desired day
/// - Returns: A `Date` object
static func 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)
dateComponents
De acuerdo con la documentación de Apple
Ejemplo:
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
En Swift 3.0, ha establecido el objeto de fecha de esta manera.
extension Date
{
init(dateString:String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
let d = dateStringFormatter.date(from: dateString)!
self(timeInterval:0, since:d)
}
}
Personalmente, creo que debería ser un inicializador fallable:
extension Date {
init?(dateString: String) {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateFormat = "yyyy-MM-dd"
if let d = dateStringFormatter.date(from: dateString) {
self.init(timeInterval: 0, since: d)
} else {
return nil
}
}
}
De lo contrario, una cadena con un formato no válido generará una excepción.
Según la respuesta de @mythz, decido publicar una versión actualizada de su extensión usando la swift3
sintaxis.
extension Date {
static func from(_ year: Int, _ month: Int, _ day: Int) -> Date?
{
let gregorianCalendar = Calendar(identifier: .gregorian)
let dateComponents = DateComponents(calendar: gregorianCalendar, year: year, month: month, day: day)
return gregorianCalendar.date(from: dateComponents)
}
}
No uso el parse
método, pero si alguien lo necesita, actualizaré esta publicación.
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.
let startDateTimeComponents = NSDateComponents()
startDateTimeComponents.year = NSCalendar.currentCalendar().components(NSCalendarUnit.Year, fromDate: date).year
startDateTimeComponents.month = NSCalendar.currentCalendar().components(NSCalendarUnit.Month, fromDate: date).month
startDateTimeComponents.day = NSCalendar.currentCalendar().components(NSCalendarUnit.Day, fromDate: date).day
startDateTimeComponents.hour = NSCalendar.currentCalendar().components(NSCalendarUnit.Hour, fromDate: time).hour
startDateTimeComponents.minute = NSCalendar.currentCalendar().components(NSCalendarUnit.Minute, fromDate: time).minute
let startDateCalendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
combinedDateTime = startDateCalendar!.dateFromComponents(startDateTimeComponents)!
De acuerdo con la Guía de formato de datos de Apple
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:)
).
Así que aquí está mi enfoque:
extension DateFormatter {
static let yyyyMMdd: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.calendar = Calendar(identifier: .iso8601)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
extension Date {
init?(yyyyMMdd: String) {
guard let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd) else { return nil }
self.init(timeInterval: 0, since: date)
}
init(dateLiteralString yyyyMMdd: String) {
let date = DateFormatter.yyyyMMdd.date(from: yyyyMMdd)!
self.init(timeInterval: 0, since: date)
}
}
Y ahora disfruta simplemente llamando:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDate
como en Objective-C?