objective c - example - ¿Creando un NSDateFormatter en Swift?
swift nsdate (4)
Si realmente está buscando un análogo directo al método en su pregunta, en Swift 3 podría hacer algo como:
class MyObject { // define static variable private static let formatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy" return formatter }() // you could use it like so func someMethod(date: Date) -> String { return MyObject.formatter.string(from: date) } }
O en Swift 2:
class MyObject { // define static variable private static let formatter: NSDateFormatter = { let formatter = NSDateFormatter() formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy" return formatter }() // you could use it like so func someMethod(date: NSDate) -> String { return MyObject.formatter.stringFromDate(date) } }
Las propiedades
static
, como las globales, disfrutan del comportamiento dedispatch_once
para sus valores predeterminados. Para obtener más información, consulte la discusióndispatch_once
al final de la entrada Archivos e Inicialización en el blog Swift de Apple.Con respecto a las mejores prácticas con los formateadores de fecha, sugeriría:
Sí, es prudente no crear y destruir innecesariamente formateadores que es probable que vuelvas a necesitar. En el video de la WWDC 2012, el rendimiento de la aplicación iOS: capacidad de respuesta , Apple nos alienta explícitamente a
Cachear un formateador por formato de fecha;
Agregue el observador para
NSLocale.currentLocaleDidChangeNotification
en Swift 3 (NSCurrentLocaleDidChangeNotification
en Swift 2) a través delNSNotificationCenter
, yNSNotificationCenter
/NSNotificationCenter
formateadores almacenados en caché si esto ocurre; yTenga en cuenta que restablecer un formato es tan costoso como recrearlo, así que evite cambiar repetidamente la cadena de formato de un formateador.
En pocas palabras, reutilice los formateadores de fecha siempre que sea posible si está utilizando el mismo formato de fecha repetidamente.
Si usa
NSDateFormatter
para analizar las cadenas de fecha para intercambiarlas con un servicio web (o almacenarlas en una base de datos), debe usar laen_US_POSIX
regionalen_US_POSIX
para evitar problemas con usuarios internacionales que podrían no estar usando calendarios gregorianos. Consulte las preguntas y respuestas técnicas de Apple n.º 1480 . (O en iOS 10 y macOS 10.12, useISO8601DateFormatter
.)Pero cuando use
dateFormat
conNSDateFormatter
/DateFormatter
, use la configuración regional actual para crear cadenas que se presentarán al usuario final, pero useen_US_POSIX
local cuando cree / analice cadenas paraen_US_POSIX
internamente dentro de la aplicación o para intercambiarlas con un servicio web.Si formatea cadenas de fecha para la interfaz de usuario, localice las cadenas evitando el uso de literales de cadena para
dateFormat
si es posible. UsadateStyle
ytimeStyle
donde puedas. Y si debe usardateFormat
personalizado, use plantillas para localizar sus cadenas. Por ejemplo, en lugar de codificarE, MMM d
, en Swift 3, usaríadateFormat(fromTemplate:options:locale:)
:formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "EdMMM", options: 0, locale: Locale.current)
O en Swift 2,
dateFormatFromTemplate(_:options:locale:)
:formatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("EdMMM", options: 0, locale: NSLocale.currentLocale())
Esto mostrará automáticamente, por ejemplo, "lunes 5 de septiembre" para los usuarios de EE. UU., Pero "lunes 5 de septiembre" para los usuarios del Reino Unido.
El
NSDateFormatter
ahora es seguro para subprocesos en iOS 7 y versiones posteriores y aplicaciones de 64 bits que se ejecutan en macOS 10.9 y versiones posteriores.
Soy nuevo en Swift y no estoy muy familiarizado con Objective-C. ¿Podría alguien ayudarme a convertir esto a Swift? Obtuve este código de las mejores prácticas de iOS de Ray Wenderlich: http://www.raywenderlich.com/31166/25-ios-app-performance-tips-tricks
¿Dónde pondrías este código? ¿Iría en un archivo de clase lleno de variables globales?
- (NSDateFormatter *)formatter {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_formatter = [[NSDateFormatter alloc] init];
_formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // twitter date format
});
return formatter;
}
Como dijo , debes tener cuidado con el rendimiento al crear DateFormatters, usa los consejos de esa sesión de la WWDC.
Estoy haciendo esto como extensiones de NSDate y NSDateFormatter (código probado en Swift 2, 3 y 4):
extension NSDate {
func PR2DateFormatterUTC() -> String {
return NSDateFormatter.PR2DateFormatterUTC.stringFromDate(self)
}
//... more formats
}
extension NSDateFormatter {
fileprivate static let PR2DateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
let timeZone = NSTimeZone(name:"UTC")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = timeZone
return formatter
}()
//... more formats
}
Uso:
let dateStringUTC = NSDate().PR2DateFormatterUTC()
He intentado aplicar el enfoque de Singleton encontrado here . Esto crea un singleton que podría cargarse con los diferentes formatos que usa dentro de su aplicación. Por ejemplo, podría acceder a él en cualquier lugar de su aplicación con formatter.fromDateTime(myString)
let formatter = FormatterFormats()
class FormatterFormats {
var dateTime: NSDateFormatter = NSDateFormatter()
class var sharedInstance:FormatterFormats {
return formatter
}
func fromDateTime(dateString: String) -> NSDate {
return dateTime.dateFromString(dateString)!
}
init() {
dateTime.dateFormat = "yyyy-MM-dd''T''HH:mm:ss.SSSZ"
}
}
Podría hacerlo así y mover el NSDateFormatter
y el onceToken
fuera de su función. Entonces puedes hacerlo como en tu ejemplo:
var theFormatter:NSDateFormatter!
var token: dispatch_once_t = 0
func formatter() ->NSDateFormatter {
dispatch_once(&token) {
theFormatter = NSDateFormatter()
theFormatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
}
return theFormatter
}
Pero como David sugirió, debería echar un vistazo a la pregunta d ispatch_once singleton .