Làm thế nào để bạn tạo một đối tượng ngày từ một ngày trong xcode nhanh chóng.
ví dụ: trong javascript bạn sẽ làm:
var day = new Date('2014-05-20');
Làm thế nào để bạn tạo một đối tượng ngày từ một ngày trong xcode nhanh chóng.
ví dụ: trong javascript bạn sẽ làm:
var day = new Date('2014-05-20');
Câu trả lời:
Swift có Date
loại riêng của mình . Không cần sử dụng NSDate
.
Trong Swift, ngày và giờ được lưu trữ trong số dấu phẩy động 64 bit đo số giây kể từ ngày tham chiếu ngày 1 tháng 1 năm 2001 lúc 00:00:00 UTC . Điều này được thể hiện trong Date
cấu trúc . Sau đây sẽ cung cấp cho bạn ngày và giờ hiện tại:
let currentDateTime = Date()
Để tạo thời gian ngày khác, bạn có thể sử dụng một trong các phương pháp sau.
Phương pháp 1
Nếu bạn biết số giây trước hoặc sau ngày tham chiếu năm 2001, bạn có thể sử dụng số đó.
let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM
Cách 2
Tất nhiên, sẽ dễ dàng hơn khi sử dụng những thứ như năm, tháng, ngày và giờ (thay vì giây tương đối) để tạo ra một Date
. Đối với điều này, bạn có thể sử dụng DateComponents
để chỉ định các thành phần và sau đó Calendar
để tạo ngày. Việc Calendar
đưa ra Date
bối cảnh. Nếu không, làm thế nào nó biết múi giờ hoặc lịch để thể hiện nó trong?
// 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)
Viết tắt múi giờ khác có thể được tìm thấy ở đây . Nếu bạn để trống, thì mặc định là sử dụng múi giờ của người dùng.
Phương pháp 3
Cách ngắn gọn nhất (nhưng không nhất thiết là tốt nhất) có thể là sử dụng DateFormatter
.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")
Các tiêu chuẩn kỹ thuật Unicode hiển thị các định dạng khác mà DateFormatter
hỗ trợ.
Xem câu trả lời đầy đủ của tôi để biết cách hiển thị ngày và giờ ở định dạng có thể đọc được. Cũng đọc những bài viết tuyệt vời này:
Điều này được thực hiện tốt nhất bằng cách sử dụng một phần mở rộng cho NSDate
lớp hiện có .
Tiện ích mở rộng sau đây thêm trình khởi tạo mới sẽ tạo một ngày trong miền địa phương hiện tại bằng cách sử dụng chuỗi ngày theo định dạng bạn đã chỉ định.
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)
}
}
Bây giờ bạn có thể tạo NSDate từ Swift chỉ bằng cách thực hiện:
NSDate(dateString:"2014-06-06")
Xin lưu ý rằng việc triển khai này không lưu trữ NSDateFormatter, điều mà bạn có thể muốn thực hiện vì lý do hiệu suất nếu bạn muốn tạo nhiều NSDate
s theo cách này.
Cũng xin lưu ý rằng việc triển khai này sẽ đơn giản gặp sự cố nếu bạn cố gắng khởi tạo một chuỗi NSDate
bằng cách chuyển một chuỗi không thể được phân tích cú pháp chính xác. Điều này là do sự hủy bỏ bắt buộc của giá trị tùy chọn được trả về dateFromString
. Nếu bạn muốn trả về một nil
phân tích cú pháp xấu, lý tưởng nhất là bạn nên sử dụng trình khởi tạo không thành công; nhưng bạn không thể làm điều đó ngay bây giờ (tháng 6 năm 2015), do hạn chế trong Swift 1.2, do đó, lựa chọn tốt nhất tiếp theo của bạn là sử dụng phương thức xuất xưởng lớp.
Một ví dụ chi tiết hơn, giải quyết cả hai vấn đề, có tại đây: 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
mỗi khi hàm được truy cập. Vì Hướng dẫn định dạng ngày tạo trạng thái Định dạng ngày không phải là thao tác rẻ . Ngoài ra, lớp này là luồng an toàn kể từ iOS7, vì vậy người ta có thể sử dụng nó một cách an toàn cho tất cả các NSDate
tiện ích mở rộng.
Swift không có loại Ngày riêng, nhưng bạn sử dụng NSDate
loại Cacao hiện có , ví dụ:
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
}
}
Mà bạn có thể sử dụng như:
var date = Date.parse("2014-05-20")
var date = Date.from(year: 2014, month: 05, day: 20)
NSDateFormatter
phương thức date(from:)
. Nó trở lại nil
. Tôi tìm thấy vấn đề này trong nhật ký sự cố vải.io.
Đây là cách tôi đã làm trong 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
}
}
Sử dụng:
let marsOpportunityLaunchDate = Date.from(year: 2003, month: 07, day: 07)
dateComponents
Theo tài liệu của Apple
Thí dụ :
var myObject = NSDate()
let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
Trong, Swift 3.0 bạn đã đặt đối tượng ngày theo cách này.
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)
}
}
Cá nhân tôi nghĩ rằng nó nên là một trình khởi tạo có sẵn:
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
}
}
}
Nếu không, một chuỗi với định dạng không hợp lệ sẽ đưa ra một ngoại lệ.
Theo câu trả lời của @mythz, tôi quyết định đăng phiên bản cập nhật của tiện ích mở rộng của mình bằng swift3
cú pháp.
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)
}
}
Tôi không sử dụng parse
phương pháp, nhưng nếu ai đó cần, tôi sẽ cập nhật bài viết này.
Tôi thường có nhu cầu kết hợp các giá trị ngày từ một nơi với các giá trị thời gian cho một nơi khác. Tôi đã viết một chức năng trợ giúp để thực hiện điều này.
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)!
Theo Hướng dẫn định dạng dữ liệu của Apple
Tạo một định dạng ngày không phải là một hoạt động rẻ tiền. Nếu bạn có khả năng sử dụng một trình định dạng thường xuyên, thì việc lưu trữ một cá thể đơn lẻ sẽ hiệu quả hơn là tạo và loại bỏ nhiều phiên bản. Một cách tiếp cận là sử dụng biến tĩnh
Và mặc dù tôi đồng ý với @Leon rằng đây phải là trình khởi tạo khả dụng, khi bạn nhập dữ liệu hạt giống, chúng ta có thể có một dữ liệu không khả dụng (giống như có UIImage(imageLiteralResourceName:)
).
Vì vậy, đây là cách tiếp cận của tôi:
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)
}
}
Và bây giờ hãy tận hưởng cuộc gọi đơn giản:
// For seed data
Date(dateLiteralString: "2020-03-30")
// When parsing data
guard let date = Date(yyyyMMdd: "2020-03-30") else { return nil }
NSDate
giống như trong Objective-C?