คุณจะสร้างวัตถุวันที่จากวันที่ใน swift xcode ได้อย่างไร
เช่นใน javascript ที่คุณต้องการ:
var day = new Date('2014-05-20');
คุณจะสร้างวัตถุวันที่จากวันที่ใน swift xcode ได้อย่างไร
เช่นใน javascript ที่คุณต้องการ:
var day = new Date('2014-05-20');
คำตอบ:
สวิฟท์มีDate
ประเภทของตัวเอง NSDate
ไม่จำเป็นต้องใช้
สวิฟท์ในวันที่และเวลาจะถูกเก็บไว้ในหลายจุด 64 บิตลอยวัดจำนวนวินาทีนับตั้งแต่วันที่อ้างอิงวันที่ 1 มกราคม 2001 00:00:00 UTC นี้จะแสดงในโครงสร้างDate
ต่อไปนี้จะให้วันที่และเวลาปัจจุบันกับคุณ:
let currentDateTime = Date()
สำหรับการสร้างวันที่อื่นคุณสามารถใช้หนึ่งในวิธีต่อไปนี้
วิธีที่ 1
หากคุณทราบจำนวนวินาทีก่อนหรือหลังวันที่อ้างอิงปี 2544 คุณสามารถใช้จำนวนนั้นได้
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
วิธีที่ 2
แน่นอนว่าการใช้สิ่งต่าง ๆ เช่นปีเดือนวันและชั่วโมง (แทนที่จะเป็นวินาทีสัมพัทธ์) จะทำให้Date
ง่ายขึ้น สำหรับสิ่งนี้คุณสามารถใช้DateComponents
เพื่อระบุส่วนประกอบจากนั้นCalendar
สร้างวันที่ Calendar
ให้Date
บริบท มิฉะนั้นจะรู้ได้อย่างไรว่าเขตเวลาหรือปฏิทินใดที่จะแสดงใน
// 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)
เวลาตัวย่อที่โซนอื่น ๆ สามารถพบได้ที่นี่ หากคุณเว้นว่างไว้ค่าเริ่มต้นคือการใช้เขตเวลาของผู้ใช้
วิธีที่ 3
วิธีรวบรัดมากที่สุด ( แต่ไม่จำเป็นต้องดีที่สุด) DateFormatter
อาจจะใช้
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
มาตรฐานทางเทคนิค Unicode แสดงรูปแบบอื่น ๆที่DateFormatter
สนับสนุน
ดูคำตอบแบบเต็มของฉันสำหรับวิธีการแสดงวันที่และเวลาในรูปแบบที่อ่านได้ อ่านบทความยอดเยี่ยมเหล่านี้ด้วย:
วิธีนี้ทำได้ดีที่สุดโดยใช้ส่วนขยายของNSDate
คลาสที่มีอยู่
ส่วนขยายต่อไปนี้เพิ่มตัวเริ่มต้นใหม่ซึ่งจะสร้างวันที่ในตำแหน่งที่ตั้งปัจจุบันโดยใช้สตริงวันที่ในรูปแบบที่คุณระบุ
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)
}
}
ตอนนี้คุณสามารถสร้าง NSDate จาก Swift ได้โดยทำดังนี้
NSDate(dateString:"2014-06-06")
โปรดทราบว่าการใช้งานนี้ไม่ได้แคช NSDateFormatter ซึ่งคุณอาจต้องการทำเพื่อเหตุผลด้านประสิทธิภาพหากคุณคาดว่าจะสร้างหลาย ๆNSDate
วิธีด้วยวิธีนี้
โปรดทราบว่าการใช้งานนี้จะล้มเหลวหากคุณพยายามเริ่มต้นNSDate
ด้วยการส่งผ่านสตริงที่ไม่สามารถแยกวิเคราะห์ได้อย่างถูกต้อง dateFromString
นี้เป็นเพราะการแกะบังคับของค่าตัวเลือกที่ส่งกลับโดย หากคุณต้องการคืนค่าการnil
แยกวิเคราะห์ที่ไม่ดีคุณควรใช้ initializer ที่ล้มเหลว แต่คุณไม่สามารถทำได้ในตอนนี้ (มิถุนายน 2015) เนื่องจากมีข้อ จำกัด ใน Swift 1.2 ดังนั้นคุณจึงเป็นทางเลือกที่ดีที่สุดถัดไปคือการใช้วิธีการเรียนแบบโรงงาน
ตัวอย่างที่ซับซ้อนมากขึ้นซึ่งอยู่ในประเด็นที่ทั้งสองอยู่ที่นี่: 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
ทุกครั้งที่เข้าถึงฟังก์ชัน ในฐานะที่เป็นวันที่จัดรูปแบบคู่มือฯสร้างวันที่จัดรูปแบบไม่ได้ดำเนินการราคาถูก นอกจากนี้คลาสยังปลอดภัยสำหรับเธรดตั้งแต่ iOS7 ดังนั้นหนึ่งสามารถใช้กับNSDate
ส่วนขยายทั้งหมดได้อย่างปลอดภัย
Swift ไม่มีประเภท Date ของตัวเอง แต่คุณต้องใช้NSDate
ประเภทCocoa ที่มีอยู่เช่น:
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
}
}
ซึ่งคุณสามารถใช้เช่น:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatter
date(from:)
มันกลับnil
มา ฉันพบปัญหานี้ในบันทึกข้อผิดพลาด fabric.io
นี่คือวิธีที่ฉันทำใน 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
}
}
การใช้งาน:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
ตัวอย่าง:
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
ใน Swift 3.0 คุณได้ตั้งค่าวัตถุวันที่ด้วยวิธีนี้
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)
}
}
โดยส่วนตัวฉันคิดว่ามันควรเป็นผู้เริ่มต้นใช้งานได้:
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
}
}
}
มิฉะนั้นสตริงที่มีรูปแบบที่ไม่ถูกต้องจะทำให้เกิดข้อยกเว้น
ตามคำตอบ @mythz ฉันตัดสินใจที่จะโพสต์ส่วนขยายเวอร์ชันอัปเดตของเขาโดยใช้swift3
ไวยากรณ์
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
วิธีการ แต่ถ้ามีคนต้องการฉันจะอัปเดตโพสต์นี้
ฉันมักจะต้องรวมค่าวันที่จากที่เดียวกับค่าเวลาสำหรับสถานที่อื่น ฉันเขียนฟังก์ชันผู้ช่วยเพื่อทำสิ่งนี้ให้สำเร็จ
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
การสร้างตัวจัดรูปแบบวันที่ไม่ใช่การดำเนินการที่ถูก หากคุณมีแนวโน้มที่จะใช้ตัวจัดรูปแบบบ่อยครั้งโดยทั่วไปจะมีประสิทธิภาพมากกว่าในการแคชอินสแตนซ์เดียวแทนที่จะสร้างและกำจัดหลายอินสแตนซ์ วิธีหนึ่งคือการใช้ตัวแปรแบบคงที่
และในขณะที่ฉันเห็นด้วยกับ @Leon ว่านี่ควรเป็น initializer ที่พร้อมใช้งานเมื่อคุณป้อนข้อมูลเมล็ดพันธุ์เราอาจมีที่ไม่พร้อมใช้งาน (เหมือนที่มีอยู่UIImage(imageLiteralResourceName:)
)
ดังนั้นนี่คือแนวทางของฉัน:
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)
}
}
และตอนนี้สนุกกับการโทรเพียง:
// 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?