如何根据给定的 NSDate 生成方便的日期范围?
我正在 Cocoa 中创建一个报告生成器,我需要生成方便的日期范围,例如“今天”、“本周”、“本月”、“今年”等。
有没有好的方法可以做到这一点?到目前为止,我的框架如下:
@interface DateRange : NSObject
{
NSDate startDate;
NSDate endDate;
}
@property (nonatomic, retain) NSDate * startDate;
@property (nonatomic, retain) NSDate * endDate;
+ (DateRange *)rangeForDayContainingDate:(NSDate *)date;
+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date;
+ (DateRange *)rangeForMonthContainingDate:(NSDate *)date;
+ (DateRange *)rangeForYearContainingDate:(NSDate *)date;
@end
一些示例用例如下:
DateRange * thisWeek = [DateRange rangeForWeekContainingDate:[NSDate date]];
DateRange * thisYear = [DateRange rangeForYearContainingDate:[NSDate date]];
本质上,我希望返回的 DateRange 对象包含目标日期周围的周、月或年的开始日期和结束日期。例如(伪代码):
NSDate * today = [August 25, 2009];
DateRange * thisWeek = [DateRange rangeForWeekContainingDate:today];
assert(thisWeek.startDate == [August 23, 3009]);
assert(thisWeek.endDate == [August 29, 3009]);
更新:
感谢 由 Kendall Helmstetter Geln 提供的答案。以下是一周范围的完整方法:
+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date
{
DateRange * range = [[self alloc] init];
// start of the week
NSDate * firstDay;
[[self calendar] rangeOfUnit:NSWeekCalendarUnit
startDate:&firstDay
interval:0
forDate:date];
[range setStartDate:firstDay];
// end of the week
NSDateComponents * oneWeek = [[NSDateComponents alloc] init];
[oneWeek setWeek:1];
[range setEndDate:[[self calendar] dateByAddingComponents:oneWeek
toDate:firstDay
options:0]];
[oneWeek release];
return [range autorelease];
}
I'm creating a report generator in Cocoa, and I need to produce convenient date ranges such as "Today", "This Week", "This Month", "This Year", etc.
Is there a good way to do this? Here is my skeleton thus far:
@interface DateRange : NSObject
{
NSDate startDate;
NSDate endDate;
}
@property (nonatomic, retain) NSDate * startDate;
@property (nonatomic, retain) NSDate * endDate;
+ (DateRange *)rangeForDayContainingDate:(NSDate *)date;
+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date;
+ (DateRange *)rangeForMonthContainingDate:(NSDate *)date;
+ (DateRange *)rangeForYearContainingDate:(NSDate *)date;
@end
Some example use cases would be as follows:
DateRange * thisWeek = [DateRange rangeForWeekContainingDate:[NSDate date]];
DateRange * thisYear = [DateRange rangeForYearContainingDate:[NSDate date]];
Essentially, I want the returned DateRange
object to contain the start and end dates for the week, month or year surrounding the target date. For example (in pseudocode):
NSDate * today = [August 25, 2009];
DateRange * thisWeek = [DateRange rangeForWeekContainingDate:today];
assert(thisWeek.startDate == [August 23, 3009]);
assert(thisWeek.endDate == [August 29, 3009]);
update:
I was able to get this working thanks to the answer provided by Kendall Helmstetter Geln. Here is the complete method for a one-week range:
+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date
{
DateRange * range = [[self alloc] init];
// start of the week
NSDate * firstDay;
[[self calendar] rangeOfUnit:NSWeekCalendarUnit
startDate:&firstDay
interval:0
forDate:date];
[range setStartDate:firstDay];
// end of the week
NSDateComponents * oneWeek = [[NSDateComponents alloc] init];
[oneWeek setWeek:1];
[range setEndDate:[[self calendar] dateByAddingComponents:oneWeek
toDate:firstDay
options:0]];
[oneWeek release];
return [range autorelease];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了完整起见,这是我的最终解决方案(感谢 Kendall Helmstetter Geln 和 jbrennan):
For the sake of completeness, here is my final solution (with thanks to Kendall Helmstetter Geln and jbrennan):
既然 timeInterval 是以秒为单位,那么只需计算一下一天有多少秒:
60 秒 * 60 分钟 * 24 小时 = 1 天。
然后,在您的
rangeForDayContainingDate
方法中,您可以提取日期组件,获取当前日期,根据该天创建一个新日期,并将小时和分钟设置为 0:00,然后创建添加时间的结束日期间隔如上计算。Well since timeInterval is in seconds, just do the math to figure out how many seconds are in a day:
60 seconds * 60 minutes * 24 hours = 1 day.
Then in your
rangeForDayContainingDate
method you could extract date components, get the current day, create a new date based on the day with hours and minutes set to 0:00, and the create the end date adding the time interval as calculated above.