Swift'deki iki NSDate / "yeni" Cocoa arasındaki gün sayısını almak için yeni ve harika bir olasılık olup olmadığını merak ediyorum.
Örneğin Ruby'deki gibi yapardım:
(end_date - start_date).to_i
Swift'deki iki NSDate / "yeni" Cocoa arasındaki gün sayısını almak için yeni ve harika bir olasılık olup olmadığını merak ediyorum.
Örneğin Ruby'deki gibi yapardım:
(end_date - start_date).to_i
Yanıtlar:
Saat farkını da göz önünde bulundurmalısınız. Örneğin, tarihleri karşılaştırırsanız 2015-01-01 10:00
ve 2015-01-02 09:00
bu tarihler arasındaki günler 0 (sıfır) olarak dönecektir, çünkü bu tarihler arasındaki fark 24 saatten azdır (23 saattir).
Amacınız iki tarih arasındaki tam gün numarasını almaksa, bu sorunu şu şekilde çözebilirsiniz:
// 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()
gereksiz gibi görünüyor): calendar.date(bySettingHour: 12, minute: 0, second: 0, of: firstDate)
.
İşte Swift 2 için cevabım:
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
vetomorrow
Birkaç Swift3 yanıtı görüyorum, bu yüzden kendi yanıtımı ekleyeceğim:
public static func daysBetween(start: Date, end: Date) -> Int {
Calendar.current.dateComponents([.day], from: start, to: end).day!
}
Adlandırma daha Swifty hissettiriyor, tek satır ve en son dateComponents()
yöntemi kullanıyor .
Benim tercüme Objective-C cevabı
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)
sonuç
<NSDateComponents: 0x10280a8a0>
Day: 4
En zor kısım, otomatik tamamlamanın tarih ve tarih arasındaki ısrarıydı NSDate?
, ancak aslında NSDate!
referansta gösterildiği gibi olmaları gerekir .
Her durumda birimi farklı şekilde belirtmek istediğinizden, bir operatörle nasıl iyi bir çözümün nasıl görüneceğini anlamıyorum. Zaman aralığını döndürebilirsiniz, ancak çok fazla kazanmayacaksınız.
.DayCalendarUnit
göre kullanımdan kaldırılmış. Şimdi .CalendarUnitDay
bunun yerine kullanmanız gerektiğine inanıyorum .
let components = cal.components(.Day, fromDate: startDate, toDate: endDate, options: [])
.Day
şimdi
Date
Yıllar, aylar, günler, saatler, dakikalar, saniye cinsinden tarihler arasında fark elde etmek için çok güzel bir uzantı
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
sinceDate
fonksiyon parametrelerinde olmalıdır .
days
ve iyi çalışıyor.
func years(since date: Date) -> Int? { return Calendar.current.dateComponents[.year], from: date, to: self).years }
ve sen de öyle diyebilirsin let y = date1.years(since: date2)
. Bu, modern adlandırma kurallarıyla daha tutarlı olabilir.
Swift 3 iOS 10 Beta 4 güncellemesi
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!
}
İşte Swift 3'ün cevabı (IOS 10 Beta için test edildi)
func daysBetweenDates(startDate: Date, endDate: Date) -> Int
{
let calendar = Calendar.current
let components = calendar.components([.day], from: startDate, to: endDate, options: [])
return components.day!
}
O zaman buna böyle diyebilirsin
let pickedDate: Date = sender.date
let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date())
print("Num of Days: \(NumOfDays)")
Swift 3. Yukarıdaki öneri için Emin Buğra Saral'a teşekkürler startOfDay
.
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)!
}
}
Kullanımı:
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
Swift'in içine yerleştirilen şeyler hala çok basit. Bu erken aşamada olmaları gerektiği gibi. Ancak, aşırı yükleme operatörleri ve küresel etki alanı işlevlerinin getirdiği riskle kendi öğelerinizi ekleyebilirsiniz. Yine de modülünüz için yerel olacaklar.
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
İşte Swift 3 için cevabım:
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!
}
Henüz Swift'e özgü standart kitaplık neredeyse yok; sadece yalın temel sayısal, dize ve koleksiyon türleri.
Uzantıları kullanarak bu tür kısayolları tanımlamak tamamen mümkündür, ancak kullanıma hazır API'ler söz konusu olduğunda "yeni" Kakao yoktur; Swift, zaten mevcut olan aynı eski ayrıntılı Cocoa API'leriyle doğrudan eşleşir.
Bu iş parçacığı bir yaşında olmasına rağmen sürümümü ekleyeceğim. Kodum şöyle görünüyor:
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."
Umarım birine yardımcı olur.
Alkış,
Erin'in yöntemi Swift 3'e güncellendi, Bu, bugünden sonraki günleri gösterir (günün saati dikkate alınmadan)
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!
}
Bu, Date
bugün ile bugün arasındaki günlerde mutlak bir fark döndürür :
extension Date {
func daysFromToday() -> Int {
return abs(Calendar.current.dateComponents([.day], from: self, to: Date()).day!)
}
}
ve sonra kullanın:
if someDate.daysFromToday() >= 7 {
// at least a week from today
}
Aşağıdaki uzantıyı kullanabilirsiniz:
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
}
}
O zaman şöyle diyebilirsiniz:
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üm cevaplar güzel. Ancak Yerelleştirmeler için iki tarih arasında birkaç ondalık gün hesaplamamız gerekir. böylece sürdürülebilir ondalık biçimi sağlayabiliriz.
// 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!
}
}
O zaman bunu gibi kullan
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."
}
}
Bu, Günleri karşılaştırmak için kesin zaman olarak gece yarısı yerine öğlen kullanma önerisini içeren, Emin'in Swift 5 cevabının güncellenmiş bir versiyonudur. Ayrıca, isteğe bağlı bir döndürerek çeşitli tarih işlevlerinin olası başarısızlıklarını da ele alır.
///
/// 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
}
Swift 3 - Bugünden bugüne kadar geçen gün sayısı
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!
}
Bunun gibi işlevi çağır
// Days from today until date
var examnDate = DateComponents()
examnDate.year = 2016
examnDate.month = 12
examnDate.day = 15
let daysCount = daysUntilDate(endDateComponents: examnDate)
daha kolay seçenek, Tarih üzerinde bir uzantı oluşturmaktır
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))
}
dizi olarak yılın ay günlerine ve saatlerine ihtiyacınız varsa bunu kullanın
var yarın = Calendar.current.date (Ekleyerek: .day, değer: 1, kime: Tarih ())!
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" }
}
}
Swift 5.2.4 çözümü:
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