开发者

NSDate troubles - or how to ignore date/timezone?

Alright I've given up on this. Here's what I'm trying to do: I have a sunrise, sunset, and the current time in a certain timezone. I want to know if it's day or night by figuring out if the current time lies between the sunrise and the sunset times.

Here's what I have:

NSLog(@"%@ - %@ - %@",currTime,sunrise,sunset);

NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc]init];
[formatter1 setDateFormat:@"hh:mm a"];
[formatter2 setDateFormat:@"EEE, dd MMM yyyy h:mm a z"];
NSDate *rise = [formatter1 dateFromString:sunrise];
NSDate *set = [formatter1 dateFromString:sunset];
NSDate *time = [formatter2 dateFromString:currTime];    
[formatter1 release];
[formatter2 release];

unsigned int flags = NSHourCalendarUnit | NSMinuteCalendarUnit;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components1 = [calendar components:flags fromDate:rise];
NSDateComponents *components2 = [calendar components:flags fromDate:set];
NSDateComponents *开发者_JAVA技巧components3 = [calendar components:flags fromDate:time];

NSDate *Sunrise = [calendar dateFromComponents:components1];
NSDate *Sunset = [calendar dateFromComponents:components2];
NSDate *Time = [calendar dateFromComponents:components3];

NSLog(@"\nSunrise: %@ \nSunset:%@ \nTime:%@",rise,set,time);
NSLog(@"\nSunrise: %@ \nSunset:%@ \nTime:%@",Sunrise,Sunset,Time);

Here's the first output:

Fri, 10 Jun 2011 4:00 am SAST - 7:46 am - 5:41 pm

And here's the second (before making it only concerned about the time, not date)

Sunrise: 1969-12-31 22:46:00 +0000

Sunset: 1970-01-01 08:41:00 +0000

Time: 2011-06-10 02:00:00 +0000

And finally here is the last output (notice how the times are messed up?):

Sunrise: 0001-12-31 22:27:01 +0000

Sunset: 0001-01-01 08:22:01 +0000

Time: 0001-01-01 01:41:01 +0000

So I wanted to pop those resulting dates into my method that checks whether it's in between the dates:

+(BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
    return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending));
}

However, until I get the date problem figured out that method won't work. :/ I need help! What am I doing wrong?


Ok, so I gave up on trying to get NSDates to work for me. The timezone issues just killed my brain for the weekend. Anyway, I decided to use BoopMeister suggestion, but it doesn't work quite like I expect. Here's an example:

Using the setup from above, I added these lines:

NSInteger riseHour = [components1 hour];
NSInteger setHour = [components2 hour];
NSInteger timeHour = [components3 hour];

NSLog(@"Rise: %i  Set: %i  Time: %i",riseHour,setHour,timeHour);

Now, when I plug in these variables: Current time: Fri, 10 Jun 2011 9:07 am CDT Sunrise: 6:33 am Sunset: 8:32 pm

However, when I output the strings from the methods above here's what I get:

Rise: 6 Set: 20 Time: 23

What the?


I would use the components you already have and not make new dates.

Starting at this point in your code:

NSDateComponents *riseComponents = [calendar components:flags fromDate:rise];
NSDateComponents *setComponents = [calendar components:flags fromDate:set];
NSDateComponents *timeComponents = [calendar components:flags fromDate:time];

And then something like

NSInteger riseHour = [riseComponents hour];
NSInteger setHour = [setComponents hour];
NSInteger timeHour = [timeComponents hour];

// Do some checks here
// If necessary do the same for the minutes ([components minute])

Comparing dates has been a performance issue in my app and since you already have the dateComponents it would be faster to make your own check and use the NSIntegers.


Okay, so as can be seen in the question, it gives the numerical presentation of the hours. Same works for the minutes. Build your checks after that.

What probably is the problem with the current time, is the calendar you use. It automatically converts the time to the time in the timezone of the calendar you use. You can also create a calendar with a string representation of the timezone. It's in the API of NSCalendar I think. Then after you made that calendar, then use that one for the current time.


One of the key things about NSDate is that it is in GMT. Always. However when you log it, it prints according to the user's locale.

Now when you do,

NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init];
[formatter1 setDateFormat:@"hh:mm a"];
NSDate *rise = [formatter1 dateFromString:sunrise];
NSDate *set = [formatter1 dateFromString:sunset];
[formatter1 release];

You are just providing information about hour, minute and whether it is AM/PM. How is it to know which day the time belongs to. It fills this lack of information by defaulting to 01/01/1970 and timezone based on the user's locale. You do provide the timezone information in the current time which might or might not be the same as the user's locale.

To fix this, you must generate a string that includes the date and timezone info for the sunset time and pass it to the date formatter with the correct format to get the date. I am assuming you must've this (or how else will you know that it is the sunset or sunrise time for that day?). Since you know the place you should be able to get the timezone info as well. Once you've the correct information to build the dates with, every comparison method that you've used will work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜