NSDate——日期与时间
objective-c 提供了类方法和以 init 开头的方法来初始化 NSDate 对象。
NSDate 类 常见的方法的用途,如下示例程序:
#import <Foundation/Foundation.h>
int main(int argc , char * argv[])
{
@autoreleasepool{
// 获取代表当前日期、时间的NSDate
NSDate* date1 = [NSDate date];
NSLog(@"%@" , date1);
// 获取从当前时间开始,一天之后的日期
NSDate* date2 = [[NSDate alloc]
initWithTimeIntervalSinceNow:3600*24];
NSLog(@"%@" , date2);
// 获取从当前时间开始,3天之前的日期
NSDate* date3 = [[NSDate alloc]
initWithTimeIntervalSinceNow: -3*3600*24];
NSLog(@"%@" , date3);
// 获取从1970年1月1日开始,20年之后的日期
NSDate* date4 = [NSDate dateWithTimeIntervalSince1970:
3600 * 24 * 366 * 20];
NSLog(@"%@" , date4);
// 获取系统当前的Locale
NSLocale* cn = [NSLocale currentLocale];
// 获取NSDate在当前Locale下对应的字符串
NSLog(@"%@" , [date1 descriptionWithLocale:cn]);
// 获取两个日期之间较早的日期
NSDate* earlier = [date1 earlierDate:date2];
// 获取两个日期之间较晚的日期
NSDate* later = [date1 laterDate:date2];
// 比较两个日期,compare:方法返回NSComparisonResult枚举值
// 该枚举类型包含NSOrderedAscending、NSOrderedSame和
// NSOrderedDescending三个值,正如它们的名字暗示的。
// 分别代表调用compare:的日期位于被比较日期之前、相同、之后。
switch ([date1 compare:date3])
{
case NSOrderedAscending:
NSLog(@"date1位于date3之前");
break;
case NSOrderedSame:
NSLog(@"date1与date3日期相等");
break;
case NSOrderedDescending:
NSLog(@"date1位于date3之后");
break;
}
// 获取两个时间之间的时间差
NSLog(@"date1与date3之间时间差%g秒"
, [date1 timeIntervalSinceDate:date3]);
// 获取指定时间与现在的时间差
NSLog(@"date2与现在间时间差%g秒"
, [date2 timeIntervalSinceNow]);
}
}
编译运行结果:
2015-10-01 08:11:01.999 923[1353:29264] 2015-10-01 00:11:01 +0000
2015-10-01 08:11:02.081 923[1353:29264] 2015-10-02 00:11:02 +0000
2015-10-01 08:11:02.082 923[1353:29264] 2015-09-28 00:11:02 +0000
2015-10-01 08:11:02.083 923[1353:29264] 1990-01-16 00:00:00 +0000
2015-10-01 08:11:02.085 923[1353:29264] Thursday, October 1, 2015 at 8:11:01 AM China Standard Time
2015-10-01 08:11:02.085 923[1353:29264] date1位于date3之后
2015-10-01 08:11:02.086 923[1353:29264] date1与date3之间时间差259200秒
2015-10-01 08:11:02.087 923[1353:29264] date2与现在间时间差86400秒
说明:NSLocale代表一个语言,国际环境——如大陆的简体中文,可用NSLocale对象代表。同样一个日期,在不同的语言,国家环境下,显示的字符串是不同的。
日期格式器——NSDateFormatter
NSDateFormatter的功能就是完成 NSDate 和 NSString 之间的转换。
转换步骤如下:
1. 创建一个NSDateFormatter对象
2. 调用NSDateFormatter的 setDateStyle:
方法——设置格式化日期,时间的风格。其中日期,时间风格支持如下几个枚举值。
1. NSDateFormatterNoStyle——不显示日期,时间的风格
2. NSDateFormatterFullStyle——显示完整的日期,时间的风格
3. NSDateFormatterLongStyle——显示"长"的日期,时间的风格
4. NSDateFormatterMediumStyle——显示"中等"的日期,时间的风格
5. NSDateFormatterShortStyle——显示"短"的日期,时间的风格
那么可不可以自己定制格式模板呢?
当然可以。调用NSDateFormatter的 setDateFormate:方法设置日期,时间的模板即可。
3. 如果需要将NSDate转换为NSString,调用NSDateFormatter的stringFromDate:
方法执行格式化即可;如果需要将NSString转换为 NSDate,调用NSDateFormatter的dateFromString:
方法执行格式化即可。
示范NSDateFormatter的功能和用法:
#import <Foundation/Foundation.h>
int main(int argc , char * argv[])
{
@autoreleasepool{
// 需要被格式化的时间
// 获取从1970年1月1日开始,20年之后的日期
NSDate* dt = [NSDate dateWithTimeIntervalSince1970:
3600 * 24 * 366 * 20];
// 创建两个NSLocale,分别代表中国、美国
NSLocale* locales[] = {
[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]
, [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]};
NSDateFormatter* df[8];
//为上面2个NSLocale创建8个DateFormat对象
for (int i = 0 ; i < 2 ; i++)
{
df[i * 4] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * 4] setDateStyle:NSDateFormatterShortStyle];
[df[i * 4] setTimeStyle:NSDateFormatterShortStyle];
// 设置NSDateFormatter的NSLocale
[df[i * 4] setLocale: locales[i]];
df[i * 4 + 1] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * 4 + 1] setDateStyle:NSDateFormatterMediumStyle];
[df[i * 4 + 1] setDateStyle:NSDateFormatterMediumStyle];
// 设置NSDateFormatter的NSLocale
[df[i * 4 + 1] setLocale: locales[i]];
df[i * 4 + 2] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * 4 + 2] setDateStyle:NSDateFormatterLongStyle];
[df[i * 4 + 2] setTimeStyle:NSDateFormatterLongStyle];
// 设置NSDateFormatter的NSLocale
[df[i * 4 + 2] setLocale: locales[i]];
df[i * 4 + 3] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * 4 + 3] setDateStyle:NSDateFormatterFullStyle];
[df[i * 4 + 3] setTimeStyle:NSDateFormatterFullStyle];
// 设置NSDateFormatter的NSLocale
[df[i * 4 + 3] setLocale: locales[i]];
}
for (int i = 0 ; i < 2 ; i++)
{
switch (i)
{
case 0:
NSLog(@"-------中国日期格式--------");
break;
case 1:
NSLog(@"-------美国日期格式--------");
break;
}
NSLog(@"SHORT格式的日期格式:%@"
, [df[i * 4] stringFromDate: dt]);
NSLog(@"MEDIUM格式的日期格式:%@"
, [df[i * 4 + 1] stringFromDate: dt]);
NSLog(@"LONG格式的日期格式:%@"
, [df[i * 4 + 2] stringFromDate: dt]);
NSLog(@"FULL格式的日期格式:%@"
, [df[i * 4 + 3] stringFromDate: dt]);
}
NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
// 设置自定义的格式器模板
[df2 setDateFormat:@"公元yyyy年MM月DD日 HH时mm分"];
// 执行格式化
NSLog(@"%@" , [df2 stringFromDate:dt]);
NSString* dateStr = @"2013-03-02";
NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
// 根据日期字符串的格式设置格式模板
[df3 setDateFormat:@"yyyy-MM-dd"];
// 将字符串转换为NSDate对象
NSDate* date2 = [df3 dateFromString: dateStr];
NSLog(@"%@" , date2);
}
}
运行结果:
2015-10-01 09:22:24.341 923[1553:58209] -------中国日期格式--------
2015-10-01 09:22:24.514 923[1553:58209] SHORT格式的日期格式:90/1/16 上午8:00
2015-10-01 09:22:24.515 923[1553:58209] MEDIUM格式的日期格式:1990年1月16日
2015-10-01 09:22:24.526 923[1553:58209] LONG格式的日期格式:1990年1月16日 GMT+8 上午8:00:00
2015-10-01 09:22:24.526 923[1553:58209] FULL格式的日期格式:1990年1月16日 星期二 中国标准时间 上午8:00:00
2015-10-01 09:22:24.527 923[1553:58209] -------美国日期格式--------
2015-10-01 09:22:24.533 923[1553:58209] SHORT格式的日期格式:1/16/90, 8:00 AM
2015-10-01 09:22:24.534 923[1553:58209] MEDIUM格式的日期格式:Jan 16, 1990
2015-10-01 09:22:24.538 923[1553:58209] LONG格式的日期格式:January 16, 1990 at 8:00:00 AM GMT+8
2015-10-01 09:22:24.539 923[1553:58209] FULL格式的日期格式:Tuesday, January 16, 1990 at 8:00:00 AM China Standard Time
2015-10-01 09:22:24.550 923[1553:58209] 公元1990年01月16日 08时00分
2015-10-01 09:22:24.588 923[1553:58209] 2013-03-01 16:00:00 +0000
日历(NSCalendar) 与日期组件(NSDateComponents)
很多时候,我们需要将 NSDate 对象的各个字段数据分开提取。为此,foundation 框架提供了NSCalendar对象,该对象包含了如下2个常用方法:
1. calendar对象 components:<#(NSCalendarUnit)#> fromDate:<#(nonnull NSDate *)#>
:从 NSDate 提取年,月,日,时,分,秒各时间段的信息。
2. calendar dateFromComponents:<#(nonnull NSDateComponents *)#>
:使用 comps 对象包含的年,月,日,时,分,秒各时间段的信息来创建 NSDate。
NSDateComponents对象:该对象专门用于封装年,月,日,时,分,秒各时间字段的信息。它只包含了,对year,month,date,day,hour,minute,second,week,weekday 等各字段的 setter 和 getter 方法。
从 NSDate 对象中分开获取各时间字段的数值的步骤如下:
- 创建NSCalendar对象
- 调用NSCalendar的
components:<#(NSCalendarUnit)#> fromDate:<#(nonnull NSDate *)#>
方法,该方法返回一个 NSDateComponents。 - 调用 NSDateComponents对象的 getter 方法获取各时间字段的值。
使用各时间字段的数值来初始化 NSDate 对象的步骤如下:
- 创建NSCalendar对象
- 创建一个NSDateComponents对象,调用该对象的 setter 方法来设置各时间字段的值。
- 调用NSCalendar的
dateFromComponents:(NSDateComponents)
方法 初始化 NSDate 对象——该方法返回一个 NSDate 对象
示例代码:
#import <Foundation/Foundation.h>
int main(int argc , char * argv[])
{
@autoreleasepool{
// 获取代表公历的Calendar对象
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
//NSGregorianCalendar
// 获取当前日期
NSDate* dt = [NSDate date];
// 定义一个时间字段的旗标,指定将会获取指定年、月、日、时、分、秒的信息
unsigned unitFlags = NSCalendarUnitYear |
NSCalendarUnitMonth | NSCalendarUnitDay |
NSCalendarUnitHour | NSCalendarUnitMinute |
NSCalendarUnitSecond | NSCalendarUnitWeekday;
// 获取不同时间字段的信息
NSDateComponents* comp = [gregorian components: unitFlags
fromDate:dt];
// 获取各时间字段的数值
NSLog(@"现在是%ld年" , comp.year);
NSLog(@"现在是%ld月 " , comp.month);
NSLog(@"现在是%ld日" , comp.day);
NSLog(@"现在是%ld时" , comp.hour);
NSLog(@"现在是%ld分" , comp.minute);
NSLog(@"现在是%ld秒" , comp.second);
NSLog(@"现在是星期%ld" , comp.weekday);
// 再次创建一个NSDateComponents对象
NSDateComponents* comp2 = [[NSDateComponents alloc]
init];
// 设置各时间字段的数值
comp2.year = 2013;
comp2.month = 4;
comp2.day = 5;
comp2.hour = 18;
comp2.minute = 34;
// 通过NSDateComponents所包含的时间字段的数值来恢复NSDate对象
NSDate *date = [gregorian dateFromComponents:comp2];
NSLog(@"获取的日期为:%@" , date);
}
}
运行结果:
2015-10-01 10:33:17.600 923[1845:79691] 现在是2015年
2015-10-01 10:33:17.601 923[1845:79691] 现在是10月
2015-10-01 10:33:17.601 923[1845:79691] 现在是1日
2015-10-01 10:33:17.601 923[1845:79691] 现在是10时
2015-10-01 10:33:17.602 923[1845:79691] 现在是33分
2015-10-01 10:33:17.602 923[1845:79691] 现在是17秒
2015-10-01 10:33:17.602 923[1845:79691] 现在是星期5
2015-10-01 10:33:17.612 923[1845:79691] 获取的日期为:2013-04-05 10:34:00 +0000
定时器(NSTimer)——让某个方法重复运行
具体步骤:
一. 调用NSTimer 的scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> invocation:<#(nonnull NSInvocation *)#> repeats:<#(BOOL)#>
或scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> target:<#(nonnull id)#> selector:<#(nonnull SEL)#> userInfo:<#(nullable id)#> repeats:<#(BOOL)#>
类方法,创建NSTimer对象。
调用该类方法时需传入的参数:
1. TimeInterval
:每次执行任务的时间间隔(单位:秒)
2. target与 selector
:指定某个对象的特定方法作为重复执行的任务
3. invocation
:该参数需要传入一个 NSInvocation 对象,其中NSInvocation 对象也是封装 target 和 selector 的,其实也是指定用某个对象的特定方法作为重复执行的任务。
4. userInfo
:用于传入额外的附加信息。
5. repeats
: 指定一个 BOOL值,控制是否需要重复执行任务。
二.为第一步的任务编写方法。
三.销毁定时器。
示例程序:
main.m
#import <Cocoa/Cocoa.h>
#import "FKAppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
// 创建一个FKAppDelegate对象,该对象实现了NSApplicationDelegate协议
FKAppDelegate* delegate = [[FKAppDelegate alloc] init];
// 获取NSApplication的单例对象
[NSApplication sharedApplication];
// 调用静态方法为Cocoa应用设置代理,将应用发生事件委托给delegate处理
[NSApp setDelegate: delegate];
// 开始程序
return NSApplicationMain(argc, (const char **)argv);
}
}
FKAppDelegate.h
#import <Cocoa/Cocoa.h>
// 实现NSApplicationDelegate协议
@interface FKAppDelegate : NSObject <NSApplicationDelegate>
// 定义一个属性来代表程序窗口
@property (strong) NSWindow *window;
@property (nonatomic, assign) int count;
@end
FKAppDelegate.m
#import "FKAppDelegate.h"
@implementation FKAppDelegate
@synthesize window;
@synthesize count;
// 当应用程序将要加载完成时激发该方法
- (void) applicationWillFinishLaunching: (NSNotification *) aNotification
{
// 创建NSWindow对象,并赋值给window
self.window = [[NSWindow alloc] initWithContentRect:
NSMakeRect(300, 300, 320, 200)
styleMask: (NSTitledWindowMask |NSMiniaturizableWindowMask
| NSClosableWindowMask)
backing: NSBackingStoreBuffered defer: NO];
// 设置窗口标题
self.window.title = @"Delegate测试";
// 创建NSTextField对象,并赋值给label变量
NSTextField * label = [[NSTextField alloc] initWithFrame: NSMakeRect(60, 120, 200, 60)];
// 为label设置属性
[label setSelectable: YES];
[label setBezeled: YES];
[label setDrawsBackground: YES];
[label setStringValue: @"疯狂iOS讲义是一本系统的iOS开发图书" ];
// 创建NSButton对象,并赋值给button变量
NSButton * button = [[NSButton alloc] initWithFrame:
NSMakeRect(120, 40, 80, 30)];
// 为button设置属性
button.title = @"确定";
[button setBezelStyle:NSRoundedBezelStyle];
[button setBounds:NSMakeRect(120, 40, 80, 30)];
// 将label、button添加到窗口中
[self.window.contentView addSubview: label];
[self.window.contentView addSubview: button];
// 启动一个定时器
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self // 指定以当前对象的info:方法作为执行任务
selector:@selector(info:)
userInfo:nil
repeats: YES]; // 指定重复执行
}
// 当应用程序加载完成时激发该方法
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// 把该窗口显示到该应用程序的前台
[self.window makeKeyAndOrderFront: self];
}
- (void) info:(NSTimer*) timer
{
NSLog(@"正在执行第%d次任务", self.count++);
// 如果count的值大于10,取消定时器
if(self.count > 10)
{
NSLog(@"取消执行定时器");
[timer invalidate];
}
}
@end