Wrong date comes back from NSDateComponents

2019-01-29 10:21发布

Why is this giving me the wrong date ?

 NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
    NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
    [components setYear:2013];
    [components setMonth:06];
    [components setDay:28];
    [components setHour:5];
    [components setMinute:00];
    NSDate *startDate1 = [myCalendar dateFromComponents:components];
    NSLog(@"start date is %@",startDate1);

start date is 2013-06-28 03:00:00 +0000

EDIT

What I want to do is the following. I have a start and endate.

For example:

start date is 2013-06-28 05:00

end date is : 2013-06-29 04:59

Then I want to check if the current date is between start and end date. I am using the following.

NSComparisonResult result1 = [now compare:startDate1];
    NSComparisonResult result2 = [now compare:endDate1];

if (result2 == NSOrderedSame && result1 == NSOrderedSame ) {
        NSLOG(@"OKE!");
 }

3条回答
Anthone
2楼-- · 2019-01-29 10:39

That's because you have to print the date using device's time zone, otherwise it's shown in UTC.

NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
    NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
    [components setYear:2013];
    [components setMonth:06];
    [components setDay:28];
    [components setHour:5];
    [components setMinute:00];
    NSDate *startDate1 = [myCalendar dateFromComponents:components];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.timeZone = [NSTimeZone systemTimeZone];
    formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSLog(@"%@", [formatter stringFromDate:startDate1]);
查看更多
男人必须洒脱
3楼-- · 2019-01-29 10:44

Probably the date is correct, but you misunderstood the log:

Logging a date is always done in TZ +0000. For example, if you are in central europe, you will have the (expected?) date 2013-06-28 05:00:00 +0200, but the log will display the normilzed date 2013-06-28 03:00:00 +0000. This is the same date and time! It is simply expressed in a different way.

+++

If your components are in TZ +0000, too, you should set the time zone of the calendar.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-29 10:58

You can check whether the current date is between two dates like this:

NSDate *now = [NSDate date];
BOOL betweenStartAndEnd = ([startDate compare:now] == NSOrderedAscending && [endDate compare:now] == NSOrderedDescending);

Your code actually checks whether the tested date is EQUAL (NSOrderedSame) to both start and end dates (which is not of course)

result2 == NSOrderedSame && result1 == NSOrderedSame

See my extended example:

NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setYear:2013];
[components setMonth:05];
[components setDay:13];
[components setHour:18];
[components setMinute:00];
NSDate *startDate = [myCalendar dateFromComponents:components];
[components setDay:15];
NSDate *endDate = [myCalendar dateFromComponents:components];

NSDate *now = [NSDate date];
BOOL betweenStartAndEnd = ([startDate compare:now] == NSOrderedAscending && [endDate compare:now] == NSOrderedDescending);

NSLog(@"Date %@ %@ between %@ and %@", now, betweenStartAndEnd ? @"IS" : @"IS NOT", startDate, endDate);

This prints out this to the console:

Date 2013-05-13 15:44:06 +0000 IS NOT between 2013-05-13 16:00:00 +0000 and 2013-05-15 16:00:00 +0000
查看更多
登录 后发表回答