比较两个NSDates的最有效/推荐方法是什么?我希望能够看到两个日期是否在同一天,无论时间如何,并且已经开始编写一些在NSDate类中使用timeIntervalSinceDate:方法的代码,并获取此值的整数除以秒数一天内。这似乎很长,我觉得我错过了一些明显的东西。
我想修复的代码是:
if (!([key compare:todaysDate] == NSOrderedDescending))
{
todaysDateSection = [eventSectionsArray count] - 1;
}
其中key和todaysDate是NSDate对象,todaysDate使用:
创建NSDate *todaysDate = [[NSDate alloc] init];
此致
戴夫
答案 0 :(得分:83)
我很惊讶没有其他答案有这个选项来获取对象的“开始日期”日期:
[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay startDate:&date1 interval:NULL forDate:date1];
[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay startDate:&date2 interval:NULL forDate:date2];
将date1
和date2
设置为各自日期的开头。如果他们是平等的,他们就在同一天。
或者这个选项:
NSUInteger day1 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit: forDate:date1];
NSUInteger day2 = [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date2];
将day1
和day2
设置为可以比较的某些任意值。如果他们是平等的,他们就在同一天。
答案 1 :(得分:72)
在进行比较之前,您将日期中的时间设置为00:00:00:
unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];
// ... necessary cleanup
然后您可以比较日期值。请参阅overview in reference documentation。
答案 2 :(得分:19)
使用iOS 8引入NSCalendar的新方法使这更容易。
- (NSComparisonResult)compareDate:(NSDate *)date1 toDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit NS_AVAILABLE(10_9, 8_0);
您可以将粒度设置为重要的单位。这忽略了所有其他单位,并限制与所选单位的比较。
答案 3 :(得分:14)
对于iOS8及更高版本,检查同一天是否出现两个日期非常简单:
[[NSCalendar currentCalendar] isDate:date1 inSameDayAsDate:date2]
答案 4 :(得分:10)
这是所有答案的简写:
NSInteger interval = [[[NSCalendar currentCalendar] components: NSDayCalendarUnit
fromDate: date1
toDate: date2
options: 0] day];
if(interval<0){
//date1<date2
}else if (interval>0){
//date2<date1
}else{
//date1=date2
}
答案 5 :(得分:6)
我使用这个小的util方法:
-(NSDate*)normalizedDateWithDate:(NSDate*)date
{
NSDateComponents* components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
fromDate: date];
return [calendar_ dateFromComponents:components]; // NB calendar_ must be initialized
}
(你显然需要一个名为calendar_
的ivar,其中包含NSCalendar
。
使用此功能,可以轻松检查日期是否如此:
[[self normalizeDate:aDate] isEqualToDate:[self normalizeDate:[NSDate date]]];
([NSDate date]
返回当前日期和时间。)
这当然与格雷戈里的建议非常相似。这种方法的缺点是它往往会创建大量临时NSDate
对象。如果您要处理大量日期,我建议您使用其他方法,例如直接比较组件,或使用NSDateComponents
个对象而不是NSDates
。
答案 6 :(得分:6)
我使用了Duncan C方法,我修正了他犯的一些错误
-(NSInteger) daysBetweenDate:(NSDate *)firstDate andDate:(NSDate *)secondDate {
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [currentCalendar components: NSDayCalendarUnit fromDate: firstDate toDate: secondDate options: 0];
NSInteger days = [components day];
return days;
}
答案 7 :(得分:3)
答案比每个人都要简单得多。 NSCalendar有一个方法
components:fromDate:toDate:options
该方法可让您使用您想要的任何单位计算两个日期之间的差异。
所以写一个像这样的方法:
-(NSInteger) daysBetweenDate: (NSDate *firstDate) andDate: (NSDate *secondDate)
{
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents components* = [currentCalendar components: NSDayCalendarUnit
fromDate: firstDate
toDate: secondDate
options: 0];
NSInteger days = [components days];
return days;
}
如果上述方法返回零,则两个日期在同一天。
答案 8 :(得分:3)
从iOS 8.0开始,您可以使用:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSComparisonResult dateComparison = [calendar compareDate:[NSDate date] toDate:otherNSDate toUnitGranularity:NSCalendarUnitDay];
如果结果是例如NSOrderedDescending,otherDate在[NSDate date]之前以天为单位。
我在NSCalendar文档中没有看到此方法,但它位于iOS 7.1 to iOS 8.0 API Differences
中答案 9 :(得分:2)
对于使用Swift 3进行编码的开发人员
if(NSCalendar.current.isDate(selectedDate, inSameDayAs: NSDate() as Date)){
// Do something
}
答案 10 :(得分:2)
使用Swift 3,根据您的需要,您可以选择以下两种模式之一来解决您的问题。
compare(_:to:toGranularity:)
方法 Calendar
有一个名为compare(_:to:toGranularity:)
的方法。 compare(_:to:toGranularity:)
有以下声明:
func compare(_ date1: Date, to date2: Date, toGranularity component: Calendar.Component) -> ComparisonResult
将给定日期与给定组件进行比较,如果它们在给定组件和所有较大组件中相同,则报告
orderedSame
,否则orderedAscending
或orderedDescending
。
下面的Playground代码显示热门使用它:
import Foundation
let calendar = Calendar.current
let date1 = Date() // "Mar 31, 2017, 2:01 PM"
let date2 = calendar.date(byAdding: .day, value: -1, to: date1)! // "Mar 30, 2017, 2:01 PM"
let date3 = calendar.date(byAdding: .hour, value: 1, to: date1)! // "Mar 31, 2017, 3:01 PM"
/* Compare date1 and date2 */
do {
let comparisonResult = calendar.compare(date1, to: date2, toGranularity: .day)
switch comparisonResult {
case ComparisonResult.orderedSame:
print("Same day")
default:
print("Not the same day")
}
// Prints: "Not the same day"
}
/* Compare date1 and date3 */
do {
let comparisonResult = calendar.compare(date1, to: date3, toGranularity: .day)
if case ComparisonResult.orderedSame = comparisonResult {
print("Same day")
} else {
print("Not the same day")
}
// Prints: "Same day"
}
dateComponents(_:from:to:)
Calendar
有一个名为dateComponents(_:from:to:)
的方法。 dateComponents(_:from:to:)
有以下声明:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
返回两个日期之间的差异。
下面的Playground代码显示热门使用它:
import Foundation
let calendar = Calendar.current
let date1 = Date() // "Mar 31, 2017, 2:01 PM"
let date2 = calendar.date(byAdding: .day, value: -1, to: date1)! // "Mar 30, 2017, 2:01 PM"
let date3 = calendar.date(byAdding: .hour, value: 1, to: date1)! // "Mar 31, 2017, 3:01 PM"
/* Compare date1 and date2 */
do {
let dateComponents = calendar.dateComponents([.day], from: date1, to: date2)
switch dateComponents.day {
case let value? where value < 0:
print("date2 is before date1")
case let value? where value > 0:
print("date2 is after date1")
case let value? where value == 0:
print("date2 equals date1")
default:
print("Could not compare dates")
}
// Prints: date2 is before date1
}
/* Compare date1 and date3 */
do {
let dateComponents = calendar.dateComponents([.day], from: date1, to: date3)
switch dateComponents.day {
case let value? where value < 0:
print("date2 is before date1")
case let value? where value > 0:
print("date2 is after date1")
case let value? where value == 0:
print("date2 equals date1")
default:
print("Could not compare dates")
}
// Prints: date2 equals date1
}
答案 11 :(得分:1)
int interval = (int)[firstTime timeIntervalSinceDate:secondTime]/(60*60*24);
if (interval!=0){
//not the same day;
}
答案 12 :(得分:1)
我的解决方案是使用NSDateFormatter进行两次转换:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyyMMdd"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDate *today = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *todayString=[dateFormat stringFromDate:today];
NSDate *todayWithoutHour=[dateFormat dateFromString:todayString];
if ([today compare:exprDate] == NSOrderedDescending)
{
//do
}
答案 13 :(得分:0)
有关NSDate的文档表明,compare:
和isEqual:
方法都会执行基本比较并对结果进行排序,尽管它们仍然是时间因素。
管理任务的最简单方法可能是创建一个新的isToday
方法,以实现以下效果:
- (bool)isToday:(NSDate *)otherDate
{
currentTime = [however current time is retrieved]; // Pardon the bit of pseudo-code
if (currentTime < [otherDate timeIntervalSinceNow])
{
return YES;
}
else
{
return NO;
}
}
答案 14 :(得分:0)
这对皮肤来说是一种特别丑陋的猫,但这是另一种方法。我不是说它很优雅,但它可能与iOS中的日期/时间支持一样接近。
bool isToday = [[NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterFullStyle timeStyle:NSDateFormatterNoStyle] isEqualToString:[NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterFullStyle timeStyle:NSDateFormatterNoStyle]];
答案 15 :(得分:0)
NSUInteger unit = NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit;
NSDateComponents *comp = [cal components:unit
fromDate:nowDate
toDate:setDate
options:0];
NSString *dMonth;
dMonth = [NSString stringWithFormat:@"%02ld",comp.month];
NSString *dDay;
dDay = [NSString stringWithFormat:@"%02ld",comp.day + (comp.hour > 0 ? 1 : 0)];
比较小时以及修复1天的差异