计算当前时间和下一个事件之间的秒数 [英] Calculate seconds between current time and next event
问题描述
这应该很简单,但它对我来说是具有挑战性的。我想知道计算 [NSDate date]
和从那时起的未来事件x秒之间的秒差的最佳方法。有几种不同类型的事件,每个事件可能每天发生多次,并且在不同的时间发生,这取决于一周中的哪一天发生。
This should be simple, but it's proving challenging for me. I'd like to know the best approach to calculating the difference in seconds between [NSDate date]
and a future event x seconds from that time. There are several different types of event, and each event may occur several times a day, and at different times, depending what day of the week it happens to be.
什么我想做的是让用户从选择器中选择一个事件类型,然后根据他们的选择在通知中心为该事件的下一次发生设置报警。我有一切工作正常,除了秒的计算。
What I am trying to do is have the user select an event type from a picker and then set an alarm in Notification Center for the next occurrence of that event based on their selection. I have everything working fine, except for the seconds calculation.
例如,假设星期一上午9点。我想确定从现在到每周二,周四和周六,每天上午10点,下午4点和晚上11点,或星期日下午1点定期发生的用户选择事件之间的秒数。你将如何最有效地处理这个问题?
So, for example, let's say it's 9am on a Monday. I'd like to determine how many seconds it would be between now and a user selected event that regularly occurs every Tuesday, Thursday, and Saturday at 10am, 4pm, and 11pm on each day, or on Sunday at 1pm. How would you approach this most efficiently?
推荐答案
当你谈到一个时间或日期,如下星期四下午1点,这是只有意义的信息在日历的上下文中。 NSDate
不会为您提供很多帮助。它可能更适当地命名 NSPointInTime
。它只是一些从早些时候,任意参考时间点已经过去的秒数。它没有工作日,前/后子午线,甚至一天中的一小时的概念。
When you're talking about a time or date like "next Thursday at 1 PM", that's information that only makes sense in the context of a calendar. NSDate
is not going to provide you with much help. It would perhaps be more appropriately named NSPointInTime
. It's just a number of seconds that have passed from some earlier, arbitrary reference point in time. It has no notion of weekdays, ante/post meridiem, or even hour of the day.
这两种对象都知道这些事情是 NSDateComponents
和 NSCalendar
。一起工作,他们可以从下星期四下午1点这样的规范创建 NSDate
。
The two objects that do know about those sorts of thing are NSDateComponents
and NSCalendar
. Working together, they can create an NSDate
from a specification like "next Thursday at 1PM".
使用 - [NSCalendar components:fromDate:]
将任何日期转换为组件,然后可以使用其他 NSDateComponents
算术对各条信息。例如,查找今天的工作日,并与星期四不同。然后使用 - [NSCalendar dateByAddingComponents:toDate:options:]
根据该偏移量创建新日期。
You can decompose any date into components using -[NSCalendar components:fromDate:]
, and you can then use other NSDateComponents
objects to perform arithmetic on the individual pieces of information. Find the weekday of today, for example, and its difference from Thursday. Then use -[NSCalendar dateByAddingComponents:toDate:options:]
to create a new date based on that offset.
@interface NSCalendar (NextWeekday)
- (NSInteger)maxWeekday;
- (NSDate *)dateFromComponents:(NSDateComponents *)comps
forNextWeekday:(NSInteger)weekday
atHour:(NSInteger)hour;
@end
@implementation NSCalendar (NextWeekday)
- (NSInteger)maxWeekday
{
return [self maximumRangeOfUnit:NSWeekdayCalendarUnit].length;
}
- (NSDate *)dateFromComponents:(NSDateComponents *)comps
forNextWeekday:(NSInteger)weekday
atHour:(NSInteger)hour
{
NSInteger diff = weekday - [comps weekday];
if( diff < 0 ){
diff += [self maxWeekday];
}
NSDateComponents * weekdayOffset = [NSDateComponents new];
[weekdayOffset setWeekday:diff];
[comps setHour:hour];
return [self dateByAddingComponents:weekdayOffset
toDate:[self dateFromComponents:comps]
options:0];
}
@end
#define GREGORIAN_THURSDAY 5
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSCalendar * cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * wednesday = [NSDateComponents new];
[wednesday setDay:3];
[wednesday setWeekday:4];
[wednesday setMonth:6];
[wednesday setYear:2013];
NSDateComponents * friday = [NSDateComponents new];
[friday setDay:5];
[friday setWeekday:6];
[friday setMonth:6];
[friday setYear:2013];
NSDateComponents * now = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit
fromDate:[NSDate date]];
NSDateComponents * lastSatOfDecember = [NSDateComponents new];
[lastSatOfDecember setDay:29];
[lastSatOfDecember setWeekday:7];
[lastSatOfDecember setMonth:12];
[lastSatOfDecember setYear:2012];
NSLog(@"From Wednesday: %@", [cal dateFromComponents:wednesday
forNextWeekday:GREGORIAN_THURSDAY
atHour:13]);
NSLog(@"From Friday: %@", [cal dateFromComponents:friday
forNextWeekday:GREGORIAN_THURSDAY
atHour:13]);
NSLog(@"From now: %@", [cal dateFromComponents:now
forNextWeekday:GREGORIAN_THURSDAY
atHour:13]);
NSLog(@"Crossing over the year: %@", [cal dateFromComponents:lastSatOfDecember
forNextWeekday:GREGORIAN_THURSDAY
atHour:13]);
}
return 0;
}
这篇关于计算当前时间和下一个事件之间的秒数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!