Come si crea un oggetto data da una data in xcode rapido.
ad esempio in JavaScript devi fare:
var day = new Date('2014-05-20');
Come si crea un oggetto data da una data in xcode rapido.
ad esempio in JavaScript devi fare:
var day = new Date('2014-05-20');
Risposte:
Swift ha il suo Date
tipo. Non c'è bisogno di usare NSDate
.
In Swift, le date e gli orari sono memorizzati in un numero in virgola mobile a 64 bit che misura il numero di secondi dalla data di riferimento del 1 gennaio 2001 alle 00:00:00 UTC . Questo è espresso nella Date
struttura . Quanto segue ti darebbe la data e l'ora correnti:
let currentDateTime = Date()
Per creare altre date-ora, è possibile utilizzare uno dei seguenti metodi.
Metodo 1
Se conosci il numero di secondi prima o dopo la data di riferimento del 2001, puoi usarlo.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Metodo 2
Certo, sarebbe più facile usare cose come anni, mesi, giorni e ore (piuttosto che secondi relativi) per fare un Date
. Per questo è possibile utilizzare DateComponents
per specificare i componenti e quindi Calendar
per creare la data. La Calendar
dà il Date
contesto. Altrimenti, come potrebbe sapere in quale fuso orario o calendario esprimerlo?
// 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)
Altre abbreviazioni del fuso orario sono disponibili qui . Se lo lasci vuoto, l'impostazione predefinita è utilizzare il fuso orario dell'utente.
Metodo 3
Il modo più conciso (ma non necessariamente il migliore) potrebbe essere l'uso DateFormatter
.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
Gli standard tecnici Unicode mostrano altri formati che DateFormatter
supportano.
Vedi la mia risposta completa per come visualizzare la data e l'ora in un formato leggibile. Leggi anche questi eccellenti articoli:
Questo è fatto meglio usando un'estensione alla NSDate
classe esistente .
La seguente estensione aggiunge un nuovo inizializzatore che creerà una data nella locale corrente usando la stringa della data nel formato specificato.
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)
}
}
Ora puoi creare un NSDate da Swift semplicemente facendo:
NSDate(dateString:"2014-06-06")
Questa implementazione non memorizza nella cache NSDateFormatter, cosa che potresti voler fare per motivi di prestazioni se ti aspetti di creare molti messaggi NSDate
in questo modo.
Si noti inoltre che questa implementazione si arresta in modo anomalo se si tenta di inizializzare un NSDate
passaggio in una stringa che non può essere analizzata correttamente. Ciò è dovuto allo spostamento forzato del valore facoltativo restituito da dateFromString
. Se si desidera restituire un nil
errore in analisi, si dovrebbe idealmente utilizzare un inizializzatore non riuscito; ma non puoi farlo ora (giugno 2015), a causa di una limitazione in Swift 1.2, quindi la scelta migliore è quella di utilizzare un metodo factory di classe.
Un esempio più elaborato, che affronta entrambi i problemi, è qui: 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
ogni volta che si accede alla funzione. Come afferma la Guida alla formattazione della data , la creazione di un formatter data non è un'operazione economica . Inoltre, la classe è thread-safe da iOS7, quindi si può tranquillamente usarla per tutte le NSDate
estensioni.
Swift non ha il proprio tipo di data, ma è necessario utilizzare il NSDate
tipo di cacao esistente , ad esempio:
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
}
}
Che puoi usare come:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatter
metodo date(from:)
. Ritorna nil
. Ho riscontrato questo problema nel registro degli arresti anomali di fabric.io.
Ecco come l'ho fatto in 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
Secondo la documentazione Apple
Esempio :
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
In Swift 3.0 hai impostato l'oggetto data in questo modo.
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 penso che dovrebbe essere un inizializzatore disponibile:
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
}
}
}
Altrimenti una stringa con un formato non valido solleverà un'eccezione.
Secondo la risposta di @mythz, decido di pubblicare la versione aggiornata della sua estensione usando la swift3
sintassi.
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)
}
}
Non uso il parse
metodo, ma se qualcuno ha bisogno, aggiornerò questo post.
Spesso ho bisogno di combinare i valori della data da un luogo con i valori dell'ora per un altro. Ho scritto una funzione di supporto per raggiungere questo obiettivo.
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)!
Secondo la Guida alla formattazione dei dati di Apple
La creazione di un formatter data non è un'operazione economica. Se è probabile che si usi frequentemente un formattatore, in genere è più efficiente memorizzare nella cache una singola istanza piuttosto che creare e smaltire più istanze. Un approccio consiste nell'utilizzare una variabile statica
E mentre sono d'accordo con @Leon che questo dovrebbe essere un inizializzatore disponibile, quando inserisci i dati di seed, potremmo averne uno che non è disponibile (proprio come c'è UIImage(imageLiteralResourceName:)
).
Quindi ecco il mio approccio:
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)
}
}
E ora divertiti semplicemente chiamando:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDate
proprio come in Objective-C?