Swift xcode içindeki bir tarihten bir tarih nesnesi nasıl oluşturulur?
örneğin javascript ile şunları yapabilirsiniz:
var day = new Date('2014-05-20');
Swift xcode içindeki bir tarihten bir tarih nesnesi nasıl oluşturulur?
örneğin javascript ile şunları yapabilirsiniz:
var day = new Date('2014-05-20');
Yanıtlar:
Swift'in kendi Date
tipi var. Kullanmanıza gerek yok NSDate
.
Swift'te tarihler ve saatler, 1 Ocak 2001 referans tarihinden bu yana 00:00:00 UTC değerinden bu yana geçen saniye sayısını ölçen 64 bit kayan noktalı bir sayıya kaydedilir . Bu Date
yapıda ifade edilir . Aşağıdakiler size güncel tarih ve saati verecektir:
let currentDateTime = Date()
Başka tarih saatleri oluşturmak için aşağıdaki yöntemlerden birini kullanabilirsiniz.
Yöntem 1
2001 referans tarihinden önceki veya sonraki saniye sayısını biliyorsanız, bunu kullanabilirsiniz.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Yöntem 2
Tabii ki, bir yapmak için yıllar, aylar, günler ve saatler (göreli saniye yerine) kullanmak daha kolay olurdu Date
. Bunun için DateComponents
bileşenleri belirtmek ve sonra Calendar
tarihi oluşturmak için kullanabilirsiniz. Calendar
Verir Date
bağlamı. Aksi takdirde, hangi saat dilimini veya takvimi ifade edeceğini nasıl bilebilir?
// 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)
Diğer saat dilimi kısaltmaları burada bulunabilir . Bunu boş bırakırsanız, varsayılan değer kullanıcının saat dilimini kullanmaktır.
Yöntem 3
En özlü yol (ama mutlaka en iyisi değil) kullanmak olabilir DateFormatter
.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
Unicode teknik standartlar diğer biçimleri göstermek olduğunu DateFormatter
destekler.
Tarih ve saatin okunabilir bir biçimde nasıl görüntüleneceği ile ilgili tam cevabımı görün . Ayrıca bu mükemmel makaleleri okuyun:
Bu en iyi, mevcut NSDate
sınıfa bir uzantı kullanılarak yapılır .
Aşağıdaki uzantı, tarih dizesini belirttiğiniz biçimde kullanarak geçerli yerel ayarda bir tarih oluşturacak yeni bir başlatıcı ekler.
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)
}
}
Artık Swift'ten bir NSDate oluşturarak şunları yapabilirsiniz:
NSDate(dateString:"2014-06-06")
Bu uygulamanın, NSDate
bu şekilde birçok s oluşturmayı umuyorsanız performans nedenleriyle yapmak isteyebileceğiniz NSDateFormatter'ı önbelleğe almadığını lütfen unutmayın .
Ayrıca, NSDate
doğru ayrıştırılamayan bir dize geçirerek bir başlatmaya çalışırsanız bu uygulamanın çökeceğini unutmayın . Bunun nedeni, döndürülen isteğe bağlı değerin zorla açılmasıdır dateFromString
. nil
Kötü ayrıştırmalarda bir geri dönmek isterseniz, ideal olarak başarısız bir başlatıcı kullanabilirsiniz; ancak Swift 1.2'deki bir sınırlama nedeniyle bunu şimdi (Haziran 2015) yapamazsınız, bu yüzden bir sonraki en iyi seçim bir sınıf fabrikası yöntemi kullanmaktır.
Her iki sorunu da ele alan daha ayrıntılı bir örnek: 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
işleve her erişildiğinde yeniden oluşturuluyor . Gibi tarihi Biçimlendirme Kılavuzu devletler oluşturmak ucuz bir işlem değildir . Ayrıca, sınıf iOS7'den beri iş parçacığı açısından güvenlidir, bu yüzden tüm NSDate
uzantılar için güvenle kullanabilirsiniz .
Swift'in kendi Tarih türü yok, ancak mevcut Kakao NSDate
türünü kullanıyorsunuz, örneğin:
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
}
}
Hangi gibi kullanabilirsiniz:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatter
yöntemi date(from:)
. Geri döner nil
. Bu sorunu fabric.io kilitlenme günlüğünde buldum.
Swift 4.2'de şöyle yaptım:
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
}
}
Kullanımı:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
Apple belgelerine göre
Misal :
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
Swift 3.0'da bu amaçla tarih nesnesi ayarladınız.
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)
}
}
Şahsen ben bir failable başlatıcı olması gerektiğini düşünüyorum:
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
}
}
}
Aksi takdirde, geçersiz biçime sahip bir dize bir istisna oluşturur.
@ Mythz cevabına göre, swift3
sözdizimini kullanarak uzantısının güncellenmiş sürümünü yayınlamaya karar verdim .
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)
}
}
parse
Yöntem kullanmıyorum , ancak birisinin ihtiyacı varsa, bu yayını güncelleyeceğim.
Sık sık bir yerden tarih değerlerini diğeri için zaman değerleriyle birleştirmem gerekiyor. Bunu başarmak için bir yardımcı fonksiyon yazdım.
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)!
Apple'ın Veri Biçimlendirme Kılavuzu'na göre
Tarih biçimlendirici oluşturmak ucuz bir işlem değildir. Bir biçimlendiriciyi sık sık kullanmanız gerekiyorsa, genellikle tek bir örneği önbelleğe almak, birden çok örneği oluşturmak ve atmaktan daha etkilidir. Bir yaklaşım statik bir değişken kullanmaktır
Ve @Leon ile bunun failable başlatıcısı olması gerektiğine katılırken, tohum verilerini girdiğinizde, falan edilemeyen bir tane olabilir (tıpkı olduğu gibi UIImage(imageLiteralResourceName:)
).
İşte yaklaşımım:
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)
}
}
Ve şimdi sadece aramanın tadını çıkarın:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDate
Objective-C gibi kullanın ?