ios 两个 NSDates 之间的天数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4739483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Number of days between two NSDates
提问by CodeGuy
How could I determine the number of days between two NSDate
values (taking into consideration time as well)?
如何确定两个NSDate
值之间的天数(也考虑时间)?
The NSDate
values are in whatever form [NSDate date]
takes.
这些NSDate
值采用任何形式[NSDate date]
。
Specifically, when a user enters the inactive state in my iPhone app, I store the following value:
具体来说,当用户在我的 iPhone 应用程序中进入非活动状态时,我存储以下值:
exitDate = [NSDate date];
And when they open the app back up, I get the current time:
当他们重新打开应用程序时,我得到了当前时间:
NSDate *now = [NSDate date];
Now I'd like to implement the following:
现在我想实现以下内容:
-(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now
回答by Brian
Here's an implementation I used to determine the number of calendar days between two dates:
这是我用来确定两个日期之间的日历天数的实现:
+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
{
NSDate *fromDate;
NSDate *toDate;
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
interval:NULL forDate:fromDateTime];
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
interval:NULL forDate:toDateTime];
NSDateComponents *difference = [calendar components:NSCalendarUnitDay
fromDate:fromDate toDate:toDate options:0];
return [difference day];
}
EDIT:
编辑:
Fantastic solution above, here's Swift version below as an extension on NSDate
:
上面很棒的解决方案,下面是 Swift 版本作为扩展NSDate
:
extension NSDate {
func numberOfDaysUntilDateTime(toDateTime: NSDate, inTimeZone timeZone: NSTimeZone? = nil) -> Int {
let calendar = NSCalendar.currentCalendar()
if let timeZone = timeZone {
calendar.timeZone = timeZone
}
var fromDate: NSDate?, toDate: NSDate?
calendar.rangeOfUnit(.Day, startDate: &fromDate, interval: nil, forDate: self)
calendar.rangeOfUnit(.Day, startDate: &toDate, interval: nil, forDate: toDateTime)
let difference = calendar.components(.Day, fromDate: fromDate!, toDate: toDate!, options: [])
return difference.day
}
}
A bit of force unwrapping going on which you may want to remove depending on your use case.
根据您的用例,您可能想要删除一些强制展开。
The above solution also works for time zones other than the current time zone, perfect for an app that shows information about places all around the world.
上述解决方案也适用于当前时区以外的时区,非常适合显示世界各地地点信息的应用程序。
回答by Biosopher
Here's the best solution I've found. Seems to utilize the Apple approved method for determining any amount of units between NSDates.
这是我找到的最佳解决方案。似乎利用 Apple 批准的方法来确定 NSDates 之间的任何单位数量。
- (int)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
NSUInteger unitFlags = NSDayCalendarUnit;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
return [components day]+1;
}
E.g. if you want months as well, then you could include 'NSMonthCalendarUnit' as a unitFlag.
例如,如果您还想要几个月,那么您可以将“NSMonthCalendarUnit”作为 unitFlag 包含在内。
To credit the original blogger, I found this info here (although there was a slight mistake that I've fixed above): http://cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-two-dates.html?showComment=1306198273659#c6501446329564880344
为了感谢原博主,我在这里找到了这个信息(虽然我在上面修复了一个小错误):http: //cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-两个日期.html?showComment=1306198273659#c6501446329564880344
回答by Emin Bugra Saral
Swift 3.0 Update
斯威夫特 3.0 更新
extension Date {
func differenceInDaysWithDate(date: Date) -> Int {
let calendar = Calendar.current
let date1 = calendar.startOfDay(for: self)
let date2 = calendar.startOfDay(for: date)
let components = calendar.dateComponents([.day], from: date1, to: date2)
return components.day ?? 0
}
}
Swift 2.0 Update
斯威夫特 2.0 更新
extension NSDate {
func differenceInDaysWithDate(date: NSDate) -> Int {
let calendar: NSCalendar = NSCalendar.currentCalendar()
let date1 = calendar.startOfDayForDate(self)
let date2 = calendar.startOfDayForDate(date)
let components = calendar.components(.Day, fromDate: date1, toDate: date2, options: [])
return components.day
}
}
Original Solution
原始解决方案
Another solution in Swift.
Swift 中的另一个解决方案。
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
如果您的目的是获取两个日期之间的确切天数,您可以像这样解决这个问题:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = 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.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
回答by jki
I use this as category method for NSDate class
我将此用作 NSDate 类的类别方法
// returns number of days (absolute value) from another date (as number of midnights beween these dates)
- (int)daysFromDate:(NSDate *)pDate {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSInteger startDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitEra
forDate:[NSDate date]];
NSInteger endDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitEra
forDate:pDate];
return abs(endDay-startDay);
}
回答by orkoden
I needed the number of days between two dates including the beginning day. e.g. days between 14-2-2012 and 16-2-2012 would produce a result of 3.
我需要两个日期之间的天数,包括开始日。例如,14-2-2012 和 16-2-2012 之间的天数将产生 3 的结果。
+ (NSInteger)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
NSUInteger unitFlags = NSDayCalendarUnit;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
NSInteger daysBetween = abs([components day]);
return daysBetween+1;
}
Note that it doesn't matter in which order you provide the dates. It will always return a positive number.
请注意,您提供日期的顺序无关紧要。它总是会返回一个正数。
回答by chris
NSDate *lastDate = [NSDate date];
NSDate *todaysDate = [NSDate date];
NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
NSTimeInterval dateDiff = lastDiff - todaysDiff;
dateDiff will then be the number of second between the two dates. Just divide by the number of seconds in a day.
dateDiff 将是两个日期之间的秒数。只需除以一天中的秒数。
回答by tooniz
@Brian
@布莱恩
Brian's answer while good, only calculates difference in days in terms of 24h chunks, but not calendar day differences. For example 23:59 on Dec 24th is only 1 minute away from Christmas Day, for the purpose of many application that is considered one day still. Brian's daysBetween function would return 0.
布赖恩的回答虽然很好,但只计算了 24 小时块的天数差异,而不是日历日差异。例如 12 月 24 日的 23:59 离圣诞节只有 1 分钟,对于许多被认为仍然是一天的应用程序而言。Brian 的 daysBetween 函数将返回 0。
Borrowing from Brian's original implementation and beginning/end of day, I use the following in my program: (NSDate beginning of day and end of day)
借用 Brian 的原始实现和一天的开始/结束,我在我的程序中使用了以下内容:(NSDate 一天的开始和一天的结束)
- (NSDate *)beginningOfDay:(NSDate *)date
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
return [cal dateFromComponents:components];
}
- (NSDate *)endOfDay:(NSDate *)date
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
[components setHour:23];
[components setMinute:59];
[components setSecond:59];
return [cal dateFromComponents:components];
}
- (int)daysBetween:(NSDate *)date1 and:(NSDate *)date2 {
NSDate *beginningOfDate1 = [self beginningOfDay:date1];
NSDate *endOfDate1 = [self endOfDay:date1];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *beginningDayDiff = [calendar components:NSDayCalendarUnit fromDate:beginningOfDate1 toDate:date2 options:0];
NSDateComponents *endDayDiff = [calendar components:NSDayCalendarUnit fromDate:endOfDate1 toDate:date2 options:0];
if (beginningDayDiff.day > 0)
return beginningDayDiff.day;
else if (endDayDiff.day < 0)
return endDayDiff.day;
else {
return 0;
}
}
回答by Mihir
Just adding an answer for those who visit this page trying to do this in Swift. The approach is pretty much the same.
只需为访问此页面并尝试在 Swift 中执行此操作的人添加一个答案即可。方法几乎相同。
private class func getDaysBetweenDates(startDate:NSDate, endDate:NSDate) -> NSInteger {
var gregorian: NSCalendar = NSCalendar.currentCalendar();
let flags = NSCalendarUnit.DayCalendarUnit
let components = gregorian.components(flags, fromDate: startDate, toDate: endDate, options: nil)
return components.day
}
This answer was found here, in the discussion section of the following method:
在以下方法的讨论部分中找到了这个答案:
components(_:fromDate:toDate:options:)
回答by PJeremyMalouf
Here is an implementation of Brian's function in Swift:
这是布赖恩函数在 Swift 中的实现:
class func daysBetweenThisDate(fromDateTime:NSDate, andThisDate toDateTime:NSDate)->Int?{
var fromDate:NSDate? = nil
var toDate:NSDate? = nil
let calendar = NSCalendar.currentCalendar()
calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &fromDate, interval: nil, forDate: fromDateTime)
calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &toDate, interval: nil, forDate: toDateTime)
if let from = fromDate {
if let to = toDate {
let difference = calendar.components(NSCalendarUnit.DayCalendarUnit, fromDate: from, toDate: to, options: NSCalendarOptions.allZeros)
return difference.day
}
}
return nil
}
回答by Hot Licks
Another approach:
另一种方法:
NSDateFormatter* dayFmt = [[NSDateFormatter alloc] init];
[dayFmt setTimeZone:<whatever time zone you want>];
[dayFmt setDateFormat:@"g"];
NSInteger firstDay = [[dayFmt stringFromDate:firstDate] integerValue];
NSInteger secondDay = [[dayFmt stringFromDate:secondDate] integerValue];
NSInteger difference = secondDay - firstDay;
Has the advantage over the timeIntervalSince...
scheme that timezone can be taken into account, and there's no ambiguity with intervals a few seconds short or long of one day.
与timeIntervalSince...
可以考虑时区的方案相比具有优势,并且一天的间隔短或长几秒钟没有歧义。
And a bit more compact and less confusing than the NSDateComponents approaches.
并且比 NSDateComponents 方法更紧凑和更少混淆。