Date和time对象允许您及时存储对特定实例的引用。您可以使用日期和时间对象来执行计算和比较,以解决日期和时间计算的极端情况。
有三个主要的类用于处理日期和时间。
NSDate允许你表示一个绝对的时间点。
NSCalendar允许您表示特定的日历,例如公历或希伯来历。它为大多数基于日期的计算提供了接口,并允许您在NSDate对象和NSDateComponents对象之间进行转换。
NSDateComponents允许您表示特定日期的组件,如小时、分钟、日、年等。
除了这些类之外,NSTimeZone还允许您表示地缘政治区域的时区信息。它简化了跨不同时区工作的任务,并执行可能受到夏令时转换影响的计算。
创建和使用Date对象来表示绝对时间点
Date对象在Cocoa中表示日期和时间。Date对象允许您存储跨地区、日历和时区有意义的绝对时间点。
使用日历和日期组件
日期组件允许您将日期分解为组成它的各个部分,例如日、月、年、小时等等。日历代表一种计算时间的特殊形式,如公历或中国历。日历对象允许您在日期对象和日期组件对象之间以及从一个日历到另一个日历之间进行转换。
执行日期和时间计算
日历和日期组件允许您执行计算,例如两个日期之间的天数或小时数,或者查找当前周中的星期日。您还可以向日期添加组件,或者在日期下降时进行检查。
日期
日期对象允许您以一种可用于日期计算和转换的方式来表示日期和时间。作为时间上的绝对点,date对象在不同的地区、时区和日历上都是有意义的。
日期的基本面
Cocoa将日期和时间表示为NSDate对象。NSDate是一个基本的Cocoa值对象。日期对象表示一个不变的时间点。因为日期是一个时间点,所以它意味着时钟时间和一天,所以没有办法定义一个date对象来表示没有时间的一天。
要理解Cocoa如何处理日期,您必须考虑NSCalendar和NSDateComponents对象。在非技术环境中,一个时间点通常由一个时钟时间和一个特定日历(如公历或希伯来历)上的一天的组合表示。支持不同的日历对于本地化非常重要。在Cocoa中,使用特定的日历将日期对象分解为日期组件,例如年、月、日、小时和分钟。相反,可以使用日历从日期组件创建日期对象。日历和日期组件对象在日历、日期组件和日历单元中有更详细的描述。
NSDate提供了用于创建日期、比较日期和计算间隔的方法。日期对象是不可变的。date对象的标准时间单位是浮点值,类型为NSTimeInterval,用秒表示。这种类型使广泛而细粒度的日期和时间值范围成为可能,在毫秒范围内精确地表示10,000年间隔的日期。
NSDate将时间计算为相对于绝对参考时间的秒:2001年1月1日的第一个瞬间,格林威治标准时间(GMT)。在此之前的日期被存储为负数;之后的日期存储为正数。作为NSDate的唯一原始方法,timeintervaleferencedate为NSDate接口中的所有其他方法提供了基础。NSDate将所有的日期和时间表示形式转换为与绝对引用日期相关的NSTimeInterval值。
Cocoa根据基于协调世界时的网络时间协议(NTP)标准实现时间。
创建日期对象
如果你想要一个表示当前时间的日期,你分配一个NSDate对象并用init初始化它:
NSDate *now = [[NSDate alloc] init];
或者使用NSDate类方法date来创建date对象。如果你想要一些时间而不是当前时间,你可以使用NSDate的initWithTimeInterval…或dateWithTimeInterval…方法;但是,通常使用更复杂的方法,使用calendar Basics中描述的日历和日期组件。
initWithTimeInterval……方法初始化与方法名称所描述的特定时间相关的日期对象。您可以(以秒为单位)指定date对象的最近时间或过去时间。若要指定比方法的引用日期早出现的日期,请使用负数秒。
清单1定义了两个日期对象。tomorrow对象距离当前日期和时间正好24小时,而yesterday恰好比当前日期和时间早24小时。
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *tomorrow = [[NSDate alloc] initWithTimeIntervalSinceNow:secondsPerDay];
NSDate *yesterday = [[NSDate alloc] initWithTimeIntervalSinceNow:-secondsPerDay];
清单2通过添加时间间隔来创建日期
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *today = [[NSDate alloc] init];
NSDate *tomorrow, *yesterday;
tomorrow = [today dateByAddingTimeInterval:secondsPerDay];
yesterday = [today dateByAddingTimeInterval:-secondsPerDay];
基本的日期计算
要比较日期,可以使用isEqualToDate:、compare:、laterDate:和previous date:方法。这些方法执行精确的比较,这意味着它们可以检测到日期之间的亚秒级差异。您可能想要比较粒度较小的日期。例如,如果两个日期相距不到一分钟,您可能会认为它们是相等的。如果是这种情况,请使用timeIntervalSinceDate:来比较这两个日期。下面的代码片段展示了如何使用timeIntervalSinceDate:查看两个日期是否在一分钟(60秒)内。
if (fabs([date2 timeIntervalSinceDate:date1]) < 60) {
// …
}
要获取日期对象和另一个时间点之间的差异,请发送一个timeIntervalSince…给date对象的消息。例如,timeIntervalSinceNow提供当前时间和接收日期对象之间的时间(以秒为单位)。
NSDate* date = [[NSDate alloc]init];
NSDate* tomorrow = [date dateByAddingTimeInterval:246060];
NSDate* yesterday = [date dateByAddingTimeInterval:-246060];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
// NSLog(@"%@",[formatter stringFromDate:tomorrow]);
// NSLog(@"%@",[formatter stringFromDate:yesterday]);
//
// NSLog(@"%d", [tomorrow isEqualToDate:yesterday]);//判断两个日期是否相等
// NSLog(@"%ld", (long)[tomorrow compare:yesterday]);//1大于
// NSLog(@"%ld", (long)[yesterday compare:tomorrow]);//-1小于
// NSLog(@"%ld", (long)[tomorrow compare:tomorrow]);//0等于
日历基础知识
NSCalendar提供了各种日历的实现。它为几种不同的日历提供数据,包括佛教日历、公历日历、希伯来日历、伊斯兰日历和日语日历(支持哪些日历取决于操作系统的发布—检查NSLocale类以确定在给定的发布中支持哪些日历)。NSCalendar与NSDateComponents类密切相关,后者的实例描述了calendrical计算所需的日期的组件元素。
日历是由NSLocale中的常量指定的。使用NSCalendar方法currentCalendar最容易获得用户首选地区的日历;你可以使用key NSLocaleCalendar从任何NSLocale对象中获取默认日历。还可以通过为所需的日历指定标识符来创建任意的日历对象。清单3显示了如何为日语日历和当前用户创建一个日历对象。
清单3创建日历对象
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSCalendar *japaneseCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSJapaneseCalendar];
NSCalendar *usersCalendar =
[[NSLocale currentLocale] objectForKey:NSLocaleCalendar];
日期组件和日历单元
使用NSDateComponents对象表示日期(例如年、日和小时)的组件元素。NSDateComponents对象可以包含绝对值或单位数量(有关使用NSDateComponents指定单位数量的示例,请参阅向日期添加组件)。要使日期组件对象有意义,您需要知道相关的日历和用途。
注意:在ios4.0及以后版本中,NSDateComponents对象可以包含日历、时区和日期对象。这允许将日期组件传递给或从方法返回,并保留它们的意义。
日、周、周、月和年的数字通常是1,但是可能有特定于日历的例外。序数,在它们出现的地方,是基于1的。有些日历可能需要将它们的基本单位概念映射到年/月/周/日/……命名法中。单元的特定值由每个日历定义,不一定与另一个日历中该单元的值一致。
清单4展示了如何创建一个date components对象,该对象可用于创建日期,其中年单元为2004年,月单元为5月,日单元为6(在公历中,这是2004年5月6日)。你也可以用它来添加2004年的单位,5个月的单位,6天的单位到一个现有的日期。未定义weekday的值,因为没有另外指定它。
清单4创建了一个date components对象
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:6];
[components setMonth:5];
[components setYear:2004];
NSInteger weekday = [components weekday]; // Undefined (== NSUndefinedDateComponent)
在日期和日期组件之间进行转换
要将日期分解为组成组件,可以使用NSCalendar方法组件:fromDate:。除了日期本身之外,您还需要在NSDateComponents对象中指定要返回的组件。为此,该方法采用一个由日历单元常数组成的位掩码。没有必要指定比您感兴趣的组件更多的组件。清单5显示了如何计算今天和工作日。
清单5获取日期的组件
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =
[gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];
NSInteger weekday = [weekdayComponents weekday];
这就为你提供了约会的绝对要素。例如,如果您请求2010年11月7日的年和日组件,则会得到2010这一年和7日这一天。如果你想知道这是一年中的哪一天,你可以使用NSCalendar类的ordinalityOfUnit:inUnit:forDate:方法。
//创建日历对象
NSCalendar* calendar = [NSCalendar currentCalendar];//
NSDate *today = [NSDate date];
NSDateComponents *weekdayComponents =
[calendar components:(NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitYear |NSCalendarUnitMonth) fromDate:today];
NSInteger day = [weekdayComponents day];//所在第几天
NSInteger weekday = [weekdayComponents weekday];//所在第几周
NSInteger yearday = [weekdayComponents year];//所在的年份
NSInteger monthday = [weekdayComponents month];//所在的月份
NSLog(@"%ld",(long)day);
NSLog(@"%ld",(long)weekday);
NSLog(@"%ld",(long)yearday);
NSLog(@"%ld",(long)monthday);
还可以从组件创建日期。您可以配置NSDateComponents的一个实例来指定日期的组件,然后使用NSCalendar方法dateFromComponents:来创建相应的日期对象。您可以根据需要(或选择)提供任意数量的组件。当没有完整的信息来计算绝对时间时,通常由日历选择默认值(如0和1),但这是特定于日历的选择。如果您提供了不一致的信息,就会执行与日历相关的消除歧义(可能会忽略一个或多个参数)。
清单6显示了如何创建一个date对象来表示(在公历中)2008年5月的第一个星期一。
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setWeekday:2]; // Monday
[components setWeekdayOrdinal:1]; // The first Monday in the month
[components setMonth:5]; // May
[components setYear:2008];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:components];
为了保证正确的行为,您必须确保使用的组件对日历有意义。指定“越界”组件(例如公历中日值为-6或2月30日)会产生未定义的行为。
NSDateComponents* components = [[NSDateComponents alloc]init];
[components setMonth:4];
//[components setWeekday:1];
[components setYear:2020];
[components setWeekOfMonth:1];
[components setDay:1];
[components setHour:14];
[components setMinute:50];
NSCalendar* calender = [NSCalendar currentCalendar];
NSDate* date = [calender dateFromComponents:components];
NSDateFormatter* dataformatter = [[NSDateFormatter alloc]init];
[dataformatter setDateFormat:@"yyyy-MM-dd HH:mm"];
NSLog(@"%@",[dataformatter stringFromDate:date]);//2020-04-01 14:50
例如,您可能希望创建一个没有诸如年份之类组件的date对象来存储您朋友的生日。虽然在技术上不可能创建无年日期,但是可以使用date组件创建一个没有指定年份的date对象,如清单7所示。
[NSDateComponents alloc] init];
[components setMonth:11];
[components setDay:7];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *birthday = [gregorian dateFromComponents:components];
从一个日历转换到另一个日历
要将一个日期的组件从一个日历转换为另一个日历—例如,从公历转换为希伯来历—您首先使用第一个日历的组件创建一个date对象,然后使用第二个日历将日期分解为组件。清单8显示了如何将日期组件从一个日历转换为另一个日历。
清单8将日期组件从一个日历转换为另一个日历
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:6];
[comps setMonth:5];
[comps setYear:2004];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
[gregorian release];
NSCalendar *hebrew = [[NSCalendar alloc]
initWithCalendarIdentifier:NSHebrewCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSMonthCalendarUnit |
NSYearCalendarUnit;
NSDateComponents *components = [hebrew components:unitFlags fromDate:date];
NSInteger day = [components day]; // 15
NSInteger month = [components month]; // 9
NSInteger year = [components year]; // 5764
执行日历计算
NSDate提供日期和时间的绝对比例和纪元,然后可以将其呈现到特定的日历中进行日历计算或用户显示。要执行日历计算,通常需要获取日期的组件元素,例如年、月和日。您应该使用本文提供的方法来处理日历计算,因为它们考虑到了一些特殊情况,比如夏令时的开始或结束以及闰年。
向日期添加组件
您可以使用dateByAddingComponents:toDate:options:方法将日期(例如小时或月)的组件添加到现有日期。您可以提供任意多的组件。清单9显示了如何计算未来一个半小时的日期。
执行日历计算
NSDate提供日期和时间的绝对比例和纪元,然后可以将其呈现到特定的日历中进行日历计算或用户显示。要执行日历计算,通常需要获取日期的组件元素,例如年、月和日。您应该使用本文提供的方法来处理日历计算,因为它们考虑到了一些特殊情况,比如夏令时的开始或结束以及闰年。
向日期添加组件
您可以使用dateByAddingComponents:toDate:options:方法将日期(例如小时或月)的组件添加到现有日期。您可以提供任意多的组件。清单9显示了如何计算未来一个半小时的日期。
清单9一个半小时后
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setHour:1];
[offsetComponents setMinute:30];
// Calculate when, according to Tom Lehrer, World War III will end
NSDate *endOfWorldWar3 = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];
清单10获得当前周的星期日
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// Get the weekday component of the current date
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:today];
/*
Create a date components to represent the number of days to subtract from the current date.
The weekday value for Sunday in the Gregorian calendar is 1, so subtract 1 from the number of days to subtract from the date in question. (If today is Sunday, subtract 0 days.)
*/
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
[componentsToSubtract setDay:(0 - ([weekdayComponents weekday] - 1))];
NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract toDate:today options:0];
/*
Optional step:
beginningOfWeek now has the same hour, minute, and second as the original date (today).
To normalize to midnight, extract the year, month, and day components and create a new date from those components.
*/
NSDateComponents *components = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:beginningOfWeek];
beginningOfWeek = [gregorian dateFromComponents:components];
清单11获得本周的开始
NSDate *today = [[NSDate alloc] init];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate:today];
确定时间的差异
有几种方法可以计算日期之间的时间。根据进行计算的上下文,用户可能期望不同的行为。无论使用哪种计算,用户都应该清楚计算是如何执行的。由于Cocoa根据NTP标准实现时间,所以这些方法在计算时忽略了闰秒。您可以使用组件:fromDate:toDate:options:来确定两个日期之间的时间差异(以秒为单位)(可以使用NSDate方法timeIntervalSinceDate:计算)。清单12显示了如何使用公历获得两个日期之间的月和日。
清单12获得两个日期之间的差异
NSDate *startDate = ...;
NSDate *endDate = ...;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags fromDate:startDate toDate:endDate options:0];
NSInteger months = [components month];
NSInteger days = [components day];
如您所料,此方法处理溢出。如果fromDate:和toDate:参数之间相隔1年零3天,而您只要求间隔的天数,那么它将为day组件返回一个值为368(闰年为369)的NSDateComponents对象。但是,该方法将计算结果截断为提供的最小单元。例如,如果fromDate:参数对应于2010年1月14日晚上11:30,而toDate:参数对应于2010年1月15日上午8:00,那么两个日期之间只有8.5小时。如果你问天数,你得到0,因为8.5小时小于1天。有些情况下这一天应该是1天。您必须决定用户在特定情况下期望的行为。如果您确实需要一个返回天数的计算,通过两个日期之间的午夜数来计算,您可以使用类似于清单13中的category to NSCalendar。
清单13天之间的两个日期,作为中间的午夜数
@implementation NSCalendar (MySpecialCalculations)
- (NSInteger)daysWithinEraFromDate:(NSDate *)startDate toDate:(NSDate *)endDate {
NSInteger startDay=[self ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:startDate];
NSInteger endDay=[self ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:endDate];
return endDay - startDay;
}
@end
这种方法通过为ordinalityOfUnit:参数指定一个不同的NSCalendarUnit值来对其他日历单元起作用。例如,您可以根据1月1日、中午12点之间出现的次数来计算年数。
不要使用此方法来比较第二个差异,因为它会在32位平台上溢出NSInteger。此方法仅在同一时代有效(在公历中,这意味着两个日期都必须是CE或都必须是BCE)。如果需要跨年代比较日期,可以使用类似于清单14中的类别。
列出两个不同时代的日期之间的14天
@implementation NSCalendar (MyOtherMethod)
- (NSInteger)daysFromDate:(NSDate *)startDate toDate:(NSDate *)endDate {
NSCalendarUnit units = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *comp1 = [self components:units fromDate:startDate];
NSDateComponents *comp2 = [self components:units fromDate endDate];
[comp1 setHour:12];
[comp2 setHour:12];
NSDate *date1 = [self dateFromComponents: comp1];
NSDate *date2 = [self dateFromComponents: comp2];
return [[self components:NSDayCalendarUnit fromDate:date1 toDate:date2 options:0] day];
}
@end
查看日期何时到来
如果您需要确定某个日期是否在当前周内(或任何单元内),您可以使用NSCalendar方法rangeOfUnit:startDate:interval:forDate:。清单15显示了一个方法,用于确定给定日期是否落在本周内。在这种情况下,周被定义为周日午夜到下一个周六午夜前的这段时间(在公历中)。
清单15确定日期是否在本周
-
(BOOL)isDateThisWeek:(NSDate *)date {
NSDate *start;
NSTimeInterval extends;
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *today = [NSDate date];
BOOL success = [calendar rangeOfUnit:NSWeekCalendarUnit startDate:&start interval:&extends forDate:today];
if(!success) {
return NO;
}NSTimeInterval dateInSecs = [date timeIntervalSinceReferenceDate];
NSTimeInterval dayStartInSecs = [start timeIntervalSinceReferenceDate];return dateInSecs > dayStartInSecs && dateInSecs < (dayStartInSecs + extends)
}
使用时区
时区会给应用程序带来很多问题。考虑以下情况。你在纽约,现在是凌晨12:30。你有一个应用程序,显示明天所有的大联盟棒球比赛。因为明天因时区不同而有所不同,所以像这样的情况必须仔细考虑。幸运的是,一些计划和NSTimeZone类的帮助大大简化了这个任务。
NSTimeZone是一个定义时区对象行为的抽象类。时区对象代表地缘政治区域。因此,这些对象有区域名。时区对象还表示格林尼治标准时间(GMT)和缩写(如PST)之间的时间偏移量,可以是正的,也可以是负的。
创建时区
时区影响由给定NSDate对象的日历对象计算的日期组件的值。您可以创建一个NSTimeZone对象,并使用它来设置NSCalendar对象的时区。默认情况下,NSCalendar在创建日历对象时为应用程序或进程使用默认时区。除非已经另外设置了默认时区,否则它是在系统首选项中设置的时区。
在大多数情况下,在创建日期对象时应该使用用户的默认时区。在某些情况下,可能需要使用任意时区。例如,用户可能希望指定一个约会是在格林尼治标准时间,因为它是在下周去伦敦的商务旅行期间。NSTimeZone提供了几个类方法来创建时区对象:timeZoneWithName:, timezonewith:,和timeZoneForSecondsFromGMT:。在大多数情况下,timeZoneWithName:提供了最准确的时区,因为它调整了夏令时,因此您必须更准确地知道创建时区的位置。
对于系统已知的完整时区名称列表,您可以使用knownTimeZoneNames类方法:
NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];
应用程序默认时区
可以使用setDefaultTimeZone:在应用程序中设置默认时区。您可以在任何时候使用defaultTimeZone类方法访问这个默认时区。使用localTimeZone类方法,您可以获得一个时区对象,该对象自动更新自身以反映对默认时区的更改。
使用时区创建日期
时区在确定日期方面起着重要的作用。考虑一个跟踪约会的简单日历应用程序。例如,假设你住在芝加哥,周二上午10点你约了牙医。不过,星期天和星期一你将在纽约。当你创造那个约会时,它是带着绝对时间的心态完成的。时间是中部时间上午10点;当你去纽约时,时间应该显示为上午11:00,因为你在不同的时区,但它是相同的绝对时间。另一方面,如果你每天早上7点起床锻炼,你肯定不希望你的闹钟在下午1点响,因为你要去都柏林出差,或者在早上5点响,因为你在洛杉矶。
NSDate对象以绝对时间存储日期。例如,清单16中创建的日期对象表示4:00 PM CDT、5:00 EDT等等。
清单16使用特定的时区从组件创建日期
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"CDT"]];
NSDateComponents *timeZoneComps = [[NSDateComponents alloc] init];
[timeZoneComps setHour:16];
//specify whatever day, month, and year is appropriate
NSDate *date = [gregorian dateFromComponents:timeZoneComps];
如果您需要创建一个与时区无关的日期,您可以将该日期存储为NSDateComponents对象—只要您存储了对相应日历的一些引用。
在iOS中,NSDateComponents对象可以包含日历、时区和日期对象。因此,可以将日历和组件一起存储。如果您使用NSDateComponents类的date方法来访问日期,请确保关联的时区是最新的。
历史上的日期
在处理过去的日期时,可能会出现许多当代日期不存在的问题。这些包括不存在的日期,以前的年代,时间流动从较高的年数移动到较低的年数(如公历中的BCE日期),以及日历转换(如从儒略历到公历的转换)。
公历没有0年
在以公历为代表的儒略历和格里高利历中,没有0年。这意味着公元前1年12月31日之后的一天是公元1年1月1日。所有提供的calendrical计算方法都考虑到了这一点,但是在从组件创建日期时,您可能需要考虑到这一点。如果您确实试图创建一个年份为0的日期,那么应该是公元前1年。此外,如果您使用负的年份值从组件创建日期,则使用天文年份编号创建日期,其中0对应于公元前1年,-1对应于公元前2年,依此类推。例如,清单17中创建的两个日期相当于表示公元前7、8年的5月7日。
清单17使用负年份表示BCE日期
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *bceDateComponents = [[NSDateComponents alloc] init];
[bceDateComponents setMonth:5];
[bceDateComponents setDay:7];
[bceDateComponents setYear:8];
[bceDateComponents setEra:0];
NSDateComponents *astronomicalDateComponents = [[NSDateComponents alloc] init];
[astronomicalDateComponents setMonth:5];
[astronomicalDateComponents setDay:7];
[astronomicalDateComponents setYear:-7];
NSDate *bceDate = [gregorian dateFromComponents:bceDateComponents];
NSDate *astronomicalDate = [gregorian dateFromComponents:astronomicalDateComponents];
//获取当前时间
NSDate* today = [NSDate date];
//初始化日历
NSCalendar* calendar = [NSCalendar currentCalendar];
//初始化日历组件
NSDateComponents* components = [calendar components:NSCalendarUnitWeekday fromDate:today];
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
[componentsToSubtract setDay:(0 - ([components weekday] - 1))];//获取s当前天上一周的周日时间
// [componentsToSubtract setDay:(([components weekday] ))];//获取当前天本周的周日时间
NSDate *beginningOfWeek = [calendar dateByAddingComponents:componentsToSubtract toDate:today options:0];
NSDateFormatter* formatter= [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSLog(@"%@",[formatter stringFromDate:beginningOfWeek]);
网友评论