Wie erstelle ich ein Datumsobjekt aus einem Datum in Swift Xcode?
zB in Javascript würden Sie tun:
var day = new Date('2014-05-20');
Wie erstelle ich ein Datumsobjekt aus einem Datum in Swift Xcode?
zB in Javascript würden Sie tun:
var day = new Date('2014-05-20');
Antworten:
Swift hat seinen eigenen Date
Typ. Keine Notwendigkeit zu verwenden NSDate
.
In Swift werden Datum und Uhrzeit in einer 64-Bit-Gleitkommazahl gespeichert, die die Anzahl der Sekunden seit dem Referenzdatum vom 1. Januar 2001 um 00:00:00 UTC misst . Dies drückt sich in der Date
Struktur aus . Folgendes gibt Ihnen das aktuelle Datum und die aktuelle Uhrzeit an:
let currentDateTime = Date()
Zum Erstellen anderer Datums- und Uhrzeitangaben können Sie eine der folgenden Methoden verwenden.
Methode 1
Wenn Sie die Anzahl der Sekunden vor oder nach dem Referenzdatum 2001 kennen, können Sie diese verwenden.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Methode 2
Natürlich wäre es einfacher, Dinge wie Jahre, Monate, Tage und Stunden (anstatt relative Sekunden) zu verwenden, um eine zu erstellen Date
. Hierzu können Sie DateComponents
die Komponenten angeben und anschließend Calendar
das Datum erstellen. Das Calendar
gibt den Date
Kontext. Wie würde es sonst wissen, in welcher Zeitzone oder in welchem Kalender es ausgedrückt werden soll?
// 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)
Weitere Zeitzonenabkürzungen finden Sie hier . Wenn Sie dieses Feld leer lassen, wird standardmäßig die Zeitzone des Benutzers verwendet.
Methode 3
Der prägnanteste Weg (aber nicht unbedingt der beste) könnte sein DateFormatter
.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
Die Unicode - technischen Standards zeigen andere Formate , dass DateFormatter
Stützen.
In meiner vollständigen Antwort erfahren Sie, wie Sie Datum und Uhrzeit in einem lesbaren Format anzeigen. Lesen Sie auch diese ausgezeichneten Artikel:
Dies geschieht am besten mit einer Erweiterung der vorhandenen NSDate
Klasse.
Die folgende Erweiterung fügt einen neuen Initialisierer hinzu, der ein Datum im aktuellen Gebietsschema unter Verwendung der Datumszeichenfolge in dem von Ihnen angegebenen Format erstellt.
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)
}
}
Jetzt können Sie aus Swift ein NSDate erstellen, indem Sie Folgendes tun:
NSDate(dateString:"2014-06-06")
Beachten Sie, dass diese Implementierung den NSDateFormatter nicht zwischenspeichert, was Sie möglicherweise aus Leistungsgründen tun möchten, wenn Sie erwarten, dass viele NSDate
s auf diese Weise erstellt werden.
Bitte beachten Sie auch, dass diese Implementierung einfach abstürzt, wenn Sie versuchen, eine zu initialisieren, NSDate
indem Sie eine Zeichenfolge übergeben, die nicht korrekt analysiert werden kann. Dies liegt am erzwungenen Entpacken des von zurückgegebenen optionalen Werts dateFromString
. Wenn Sie eine nil
fehlerhafte Analyse zurückgeben möchten, verwenden Sie idealerweise einen fehlerhaften Initialisierer. Aufgrund einer Einschränkung in Swift 1.2 können Sie dies jetzt (Juni 2015) nicht tun. Daher ist die nächstbeste Wahl die Verwendung einer Klassenfactory-Methode.
Ein ausführlicheres Beispiel, das beide Probleme behandelt, finden Sie hier: 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
jedem Zugriff auf die Funktion. Wie Datumsformatierung Handbuch besagt ein Datum Erstellen Formatter kein billiges Betrieb ist . Außerdem ist die Klasse seit iOS7 threadsicher, sodass sie sicher für alle NSDate
Erweiterungen verwendet werden kann.
Swift hat keinen eigenen Datumstyp, aber Sie können den vorhandenen Kakaotyp NSDate
verwenden, z.
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
}
}
Welche Sie verwenden können wie:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatter
Methode date(from:)
. Es kehrt zurück nil
. Ich habe dieses Problem im Absturzprotokoll von Fabric.io gefunden.
So habe ich es in Swift 4.2 gemacht:
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
}
}
Verwendung:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
Laut Apple-Dokumentation
Beispiel:
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
In Swift 3.0 haben Sie auf diese Weise ein Datumsobjekt festgelegt.
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)
}
}
Persönlich denke ich, dass es ein fehlerhafter Initialisierer sein sollte:
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
}
}
}
Andernfalls löst eine Zeichenfolge mit einem ungültigen Format eine Ausnahme aus.
Laut @mythz Antwort entscheide ich mich, eine aktualisierte Version seiner Erweiterung mit swift3
Syntax zu veröffentlichen.
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)
}
}
Ich benutze keine parse
Methode, aber wenn jemand benötigt, werde ich diesen Beitrag aktualisieren.
Ich muss oft Datumswerte von einem Ort mit Zeitwerten für einen anderen kombinieren. Ich habe eine Hilfsfunktion geschrieben, um dies zu erreichen.
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)!
Laut Apples Datenformatierungshandbuch
Das Erstellen eines Datumsformatierers ist keine billige Operation. Wenn Sie wahrscheinlich häufig einen Formatierer verwenden, ist es in der Regel effizienter, eine einzelne Instanz zwischenzuspeichern, als mehrere Instanzen zu erstellen und zu entsorgen. Ein Ansatz besteht darin, eine statische Variable zu verwenden
Und obwohl ich @Leon zustimme, dass dies ein fehlgeschlagener Initialisierer sein sollte, könnten wir bei der Eingabe von Startdaten einen haben, der nicht fehlgeschlagen werden kann (genau wie es ihn gibt UIImage(imageLiteralResourceName:)
).
Also hier ist mein Ansatz:
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)
}
}
Und jetzt viel Spaß beim Anrufen:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDate
genau wie in Objective-C?