Tôi đang tự hỏi liệu có khả năng mới và tuyệt vời nào đó để nhận được số ngày giữa hai NSDates trong Swift / Cocoa "mới" không?
Ví dụ như trong Ruby, tôi sẽ làm:
(end_date - start_date).to_i
Tôi đang tự hỏi liệu có khả năng mới và tuyệt vời nào đó để nhận được số ngày giữa hai NSDates trong Swift / Cocoa "mới" không?
Ví dụ như trong Ruby, tôi sẽ làm:
(end_date - start_date).to_i
Câu trả lời:
Bạn cũng phải xem xét sự khác biệt về thời gian. Ví dụ: nếu bạn so sánh ngày 2015-01-01 10:00
và 2015-01-02 09:00
, ngày giữa những ngày đó sẽ trả về là 0 (không) vì sự khác biệt giữa những ngày đó là dưới 24 giờ (đó là 23 giờ).
Nếu mục đích của bạn là lấy số ngày chính xác giữa hai ngày, bạn có thể giải quyết vấn đề này như sau:
// Assuming that firstDate and secondDate are defined
// ...
let calendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.Day
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: [])
components.day // This will return the number of day(s) between dates
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: firstDate)
let date2 = calendar.startOfDay(for: secondDate)
let components = calendar.dateComponents([.day], from: date1, to: date2)
calendar.date(bySettingHour: 12, minute: 00, second: 00, of: calendar.startOfDay(for: firstDate))
startOfDay()
dường như là không cần thiết) : calendar.date(bySettingHour: 12, minute: 0, second: 0, of: firstDate)
.
Đây là câu trả lời của tôi cho Swift 2:
func daysBetweenDates(startDate: NSDate, endDate: NSDate) -> Int
{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])
return components.day
}
today
vàtomorrow
Tôi thấy một vài câu trả lời Swift3 nên tôi sẽ thêm câu trả lời của riêng mình:
public static func daysBetween(start: Date, end: Date) -> Int {
Calendar.current.dateComponents([.day], from: start, to: end).day!
}
Việc đặt tên có cảm giác Swifty hơn, nó là một dòng và sử dụng dateComponents()
phương pháp mới nhất .
Tôi đã dịch câu trả lời Objective-C của mình
let start = "2010-09-01"
let end = "2010-09-05"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let startDate:NSDate = dateFormatter.dateFromString(start)
let endDate:NSDate = dateFormatter.dateFromString(end)
let cal = NSCalendar.currentCalendar()
let unit:NSCalendarUnit = .Day
let components = cal.components(unit, fromDate: startDate, toDate: endDate, options: nil)
println(components)
kết quả
<NSDateComponents: 0x10280a8a0>
Day: 4
Phần khó nhất là tính năng tự động hoàn thành khẳng định từ Ngày đến ngày sẽ như vậy NSDate?
, nhưng thực sự chúng phải NSDate!
như được hiển thị trong tham chiếu.
Tôi không thấy giải pháp tốt với toán tử sẽ như thế nào, vì bạn muốn chỉ định đơn vị khác nhau trong mỗi trường hợp. Bạn có thể trả lại khoảng thời gian, nhưng bạn sẽ không thu được nhiều.
.DayCalendarUnit
không được dùng nữa. Tôi tin rằng bây giờ bạn nên sử dụng .CalendarUnitDay
thay thế.
let components = cal.components(.Day, fromDate: startDate, toDate: endDate, options: [])
.Day
tại
Ở đây rất hay, Date
tiện ích mở rộng để có sự khác biệt giữa các ngày trong năm, tháng, ngày, giờ, phút, giây
extension Date {
func years(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year
}
func months(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.month], from: sinceDate, to: self).month
}
func days(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.day], from: sinceDate, to: self).day
}
func hours(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.hour], from: sinceDate, to: self).hour
}
func minutes(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.minute], from: sinceDate, to: self).minute
}
func seconds(sinceDate: Date) -> Int? {
return Calendar.current.dateComponents([.second], from: sinceDate, to: self).second
}
}
date
nên có sinceDate
trong các tham số chức năng.
days
và nó hoạt động tốt.
func years(since date: Date) -> Int? { return Calendar.current.dateComponents[.year], from: date, to: self).years }
, và bạn có thể gọi nó là let y = date1.years(since: date2)
. Điều đó có thể phù hợp hơn với các quy ước đặt tên hiện đại.
Cập nhật cho Swift 3 iOS 10 Beta 4
func daysBetweenDates(startDate: Date, endDate: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)
return components.day!
}
Đây là câu trả lời cho Swift 3 (được thử nghiệm cho IOS 10 Beta)
func daysBetweenDates(startDate: Date, endDate: Date) -> Int
{
let calendar = Calendar.current
let components = calendar.components([.day], from: startDate, to: endDate, options: [])
return components.day!
}
Sau đó, bạn có thể gọi nó như thế này
let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
print("Num of Days: \(NumOfDays)")
Swift 3. Cảm ơn Emin Buğra Saral ở trên về startOfDay
gợi ý.
extension Date {
func daysBetween(date: Date) -> Int {
return Date.daysBetween(start: self, end: date)
}
static func daysBetween(start: Date, end: Date) -> Int {
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: start)
let date2 = calendar.startOfDay(for: end)
let a = calendar.dateComponents([.day], from: date1, to: date2)
return a.value(for: .day)!
}
}
Sử dụng:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let start = dateFormatter.date(from: "2017-01-01")!
let end = dateFormatter.date(from: "2018-01-01")!
let diff = Date.daysBetween(start: start, end: end) // 365
Những thứ được tích hợp trong swift vẫn rất cơ bản. Vì họ phải ở giai đoạn đầu này. Nhưng bạn có thể thêm nội dung của riêng mình với rủi ro đi kèm với các toán tử quá tải và các hàm miền toàn cầu. Tuy nhiên, chúng sẽ là cục bộ cho mô-đun của bạn.
let now = NSDate()
let seventies = NSDate(timeIntervalSince1970: 0)
// Standard solution still works
let days = NSCalendar.currentCalendar().components(.CalendarUnitDay,
fromDate: seventies, toDate: now, options: nil).day
// Flashy swift... maybe...
func -(lhs:NSDate, rhs:NSDate) -> DateRange {
return DateRange(startDate: rhs, endDate: lhs)
}
class DateRange {
let startDate:NSDate
let endDate:NSDate
var calendar = NSCalendar.currentCalendar()
var days: Int {
return calendar.components(.CalendarUnitDay,
fromDate: startDate, toDate: endDate, options: nil).day
}
var months: Int {
return calendar.components(.CalendarUnitMonth,
fromDate: startDate, toDate: endDate, options: nil).month
}
init(startDate:NSDate, endDate:NSDate) {
self.startDate = startDate
self.endDate = endDate
}
}
// Now you can do this...
(now - seventies).months
(now - seventies).days
Đây là câu trả lời của tôi cho Swift 3:
func daysBetweenDates(startDate: NSDate, endDate: NSDate, inTimeZone timeZone: TimeZone? = nil) -> Int {
var calendar = Calendar.current
if let timeZone = timeZone {
calendar.timeZone = timeZone
}
let dateComponents = calendar.dateComponents([.day], from: startDate.startOfDay, to: endDate.startOfDay)
return dateComponents.day!
}
Hầu như không có bất kỳ thư viện tiêu chuẩn dành riêng cho Swift nào; chỉ là các kiểu số, chuỗi và tập hợp cơ bản.
Hoàn toàn có thể xác định các đường tắt như vậy bằng cách sử dụng các tiện ích mở rộng, nhưng theo như các API ngoài hộp thực tế, không có Ca cao "mới"; Swift chỉ ánh xạ trực tiếp đến các API Cocoa dài dòng cũ giống như chúng đã tồn tại.
Tôi sẽ thêm phiên bản của mình mặc dù chủ đề này đã được một năm. Mã của tôi trông như thế này:
var name = txtName.stringValue // Get the users name
// Get the date components from the window controls
var dateComponents = NSDateComponents()
dateComponents.day = txtDOBDay.integerValue
dateComponents.month = txtDOBMonth.integerValue
dateComponents.year = txtDOBYear.integerValue
// Make a Gregorian calendar
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
// Get the two dates we need
var birthdate = calendar?.dateFromComponents(dateComponents)
let currentDate = NSDate()
var durationDateComponents = calendar?.components(NSCalendarUnit.CalendarUnitDay, fromDate: birthdate!, toDate: currentDate, options: nil)
let numberOfDaysAlive = durationDateComponents?.day
println("\(numberOfDaysAlive!)")
txtGreeting.stringValue = "Hello \(name), You have been alive for \(numberOfDaysAlive!) days."
Tôi hi vọng nó giúp ích cho ai đó.
Chúc mừng,
Phương thức của Erin được cập nhật lên Swift 3, Điều này hiển thị các ngày kể từ hôm nay (bất kể thời gian trong ngày)
func daysBetweenDates( endDate: Date) -> Int
let calendar: Calendar = Calendar.current
let date1 = calendar.startOfDay(for: Date())
let date2 = calendar.startOfDay(for: secondDate)
return calendar.dateComponents([.day], from: date1, to: date2).day!
}
Điều này trả lại sự khác biệt tuyệt đối về số ngày giữa một số Date
và hôm nay:
extension Date {
func daysFromToday() -> Int {
return abs(Calendar.current.dateComponents([.day], from: self, to: Date()).day!)
}
}
và sau đó sử dụng nó:
if someDate.daysFromToday() >= 7 {
// at least a week from today
}
Bạn có thể sử dụng tiện ích mở rộng sau:
public extension Date {
func daysTo(_ date: Date) -> Int? {
let calendar = Calendar.current
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: self)
let date2 = calendar.startOfDay(for: date)
let components = calendar.dateComponents([.day], from: date1, to: date2)
return components.day // This will return the number of day(s) between dates
}
}
Sau đó, bạn có thể gọi nó như thế này:
startDate.daysTo(endDate)
Swift 3.2
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
Tất cả câu trả lời là tốt. Nhưng đối với Bản địa hóa, chúng tôi cần tính số ngày thập phân ở giữa hai ngày. để chúng tôi có thể cung cấp định dạng thập phân bền vững.
// This method returns the fractional number of days between to dates
func getFractionalDaysBetweenDates(date1: Date, date2: Date) -> Double {
let components = Calendar.current.dateComponents([.day, .hour], from: date1, to: date2)
var decimalDays = Double(components.day!)
decimalDays += Double(components.hour!) / 24.0
return decimalDays
}
extension Date {
func daysFromToday() -> Int {
return Calendar.current.dateComponents([.day], from: self, to: Date()).day!
}
}
Sau đó sử dụng nó như
func dayCount(dateString: String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd,yyyy hh:mm a"
let fetchedDate = dateFormatter.date(from: dateString)
let day = fetchedDate?.daysFromToday()
if day! > -1{
return "\(day!) days passed."
}else{
return "\(day! * -1) days left."
}
}
Swift 3 - Các ngày từ hôm nay cho đến ngày
func daysUntilDate(endDateComponents: DateComponents) -> Int
{
let cal = Calendar.current
var components = cal.dateComponents([.era, .year, .month, .day], from: NSDate() as Date)
let today = cal.date(from: components)
let otherDate = cal.date(from: endDateComponents)
components = cal.dateComponents([Calendar.Component.day], from: (today! as Date), to: otherDate!)
return components.day!
}
Gọi chức năng như thế này
// Days from today until date
var examnDate = DateComponents()
examnDate.year = 2016
examnDate.month = 12
examnDate.day = 15
let daysCount = daysUntilDate(endDateComponents: examnDate)
tùy chọn dễ dàng hơn sẽ là tạo tiện ích mở rộng vào Ngày
public extension Date {
public var currentCalendar: Calendar {
return Calendar.autoupdatingCurrent
}
public func daysBetween(_ date: Date) -> Int {
let components = currentCalendar.dateComponents([.day], from: self, to: date)
return components.day!
}
}
func completeOffset(from date:Date) -> String? {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .brief
return formatter.string(from: Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date, to: self))
}
nếu bạn cần năm tháng ngày và giờ như chuỗi sử dụng
var Tomorrow = Calendar.current.date (byAdding: .day, value: 1, to: Date ())!
let dc = tomorrow.completeOffset (from: Date ())
Swift 4
func getDateHeader(indexPath: Int) -> String {
let formatter2 = DateFormatter()
formatter2.dateFormat = "MM-dd-yyyy"
var dateDeadline : Date?
dateDeadline = formatter2.date(from: arrCompletedDate[indexPath] as! String)
let currentTime = dateDeadline?.unixTimestamp
let calendar = NSCalendar.current
let date = NSDate(timeIntervalSince1970: Double(currentTime!))
if calendar.isDateInYesterday(date as Date) { return "Yesterday" }
else if calendar.isDateInToday(date as Date) { return "Today" }
else if calendar.isDateInTomorrow(date as Date) { return "Tomorrow" }
else {
let startOfNow = calendar.startOfDay(for: NSDate() as Date)
let startOfTimeStamp = calendar.startOfDay(for: date as Date)
let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
let day = components.day!
if day < 1 { return "\(abs(day)) days ago" }
else { return "In \(day) days" }
}
}
Đây là phiên bản cập nhật của câu trả lời của Emin dành cho Swift 5, kết hợp đề xuất sử dụng buổi trưa thay vì nửa đêm làm thời gian xác định để so sánh các ngày. Nó cũng xử lý lỗi tiềm ẩn của các chức năng ngày khác nhau bằng cách trả về một tùy chọn.
///
/// This is an approximation; it does not account for time differences. It will set the time to 1200 (noon) and provide the absolute number
/// of days between now and the given date. If the result is negative, it should be read as "days ago" instead of "days from today."
/// Returns nil if something goes wrong initializing or adjusting dates.
///
func daysFromToday() -> Int?
{
let calendar = NSCalendar.current
// Replace the hour (time) of both dates with noon. (Noon is less likely to be affected by DST changes, timezones, etc. than midnight.)
guard let date1 = calendar.date(bySettingHour: 12, minute: 00, second: 00, of: calendar.startOfDay(for: Date())),
let date2 = calendar.date(bySettingHour: 12, minute: 00, second: 00, of: calendar.startOfDay(for: self)) else
{
return nil
}
return calendar.dateComponents([.day], from: date1, to: date2).day
}
Giải pháp Swift 5.2.4:
import UIKit
let calendar = Calendar.current
let start = "2010-09-01"
let end = "2010-09-05"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let firstDate = dateFormatter.date(from: start)!
let secondDate = dateFormatter.date(from: end)!
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: firstDate)
let date2 = calendar.startOfDay(for: secondDate)
let components = calendar.dateComponents([Calendar.Component.day], from: date1, to: date2)
components.day // This will return the number of day(s) between dates
func simpleIndex(ofDate: Date) -> Int {
// index here just means today 0, yesterday -1, tomorrow 1 etc.
let c = Calendar.current
let todayRightNow = Date()
let d = c.date(bySetting: .hour, value: 13, of: ofDate)
let t = c.date(bySetting: .hour, value: 13, of: todayRightNow)
if d == nil || today == nil {
print("weird problem simpleIndex#ofDate")
return 0
}
let r = c.dateComponents([.day], from: today!, to: d!)
// yesterday is negative one, tomorrow is one
if let o = r.value(for: .day) {
return o
}
else {
print("another weird problem simpleIndex#ofDate")
return 0
}
}
let calendar = NSCalendar.currentCalendar();
let component1 = calendar.component(.Day, fromDate: fromDate)
let component2 = calendar.component(.Day, fromDate: toDate)
let difference = component1 - component2