【问题标题】:NSDate troubles - or how to ignore date/timezone?NSDate 问题 - 或如何忽略日期/时区?
【发布时间】:2011-06-10 08:26:29
【问题描述】:

好吧,我已经放弃了。这就是我想做的事情:我有一个日出、日落和某个时区的当前时间。我想通过确定当前时间是否介于日出和日落时间之间来知道是白天还是黑夜。

这是我所拥有的:

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 *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);

这是第一个输出:

2011 年 6 月 10 日星期五上午 4:00 SAST - 上午 7:46 - 下午 5:41

这是第二个(在使它只关心时间而不是日期之前)

日出:1969-12-31 22:46:00 +0000

日落:1970-01-01 08:41:00 +0000

时间:2011-06-10 02:00:00 +0000

最后是最后的输出(注意时间是怎么搞砸的?):

日出:0001-12-31 22:27:01 +0000

日落:0001-01-01 08:22:01 +0000

时间:0001-01-01 01:41:01 +0000

所以我想将这些生成的日期弹出到我的方法中,以检查它是否在日期之间:

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

但是,在我发现日期问题之前,我发现该方法不起作用。 :/ 我需要帮助!我做错了什么?


好的,所以我放弃了尝试让NSDates 为我工作。时区问题刚刚杀死了我周末的大脑。无论如何,我决定使用BoopMeister 建议,但它并不像我预期的那样工作。这是一个例子:

使用上面的设置,我添加了以下几行:

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

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

现在,当我插入这些变量时: 当前时间:Fri, 10 Jun 2011 9:07 am CDT 日出:6:33 am 夕阳:8:32 pm

但是,当我从上面的方法中输出字符串时,我得到的是:

上升:6 集:20 时间:23

什么?

【问题讨论】:

  • 前段时间我遇到了同样的问题,实际上我最终放弃了NSDate,而只是编写了自己的日期方法。不过,期待看看其他人是否对此有答案。
  • 我不想放弃 NSDate。我喜欢它,但它讨厌我。

标签: iphone objective-c nsdate nsdateformatter


【解决方案1】:

我会使用你已经拥有的组件而不是新的日期。

从您的代码中的这一点开始:

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

然后像

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])

比较日期一直是我的应用程序中的一个性能问题,由于您已经拥有 dateComponents,因此您自己检查并使用 NSIntegers 会更快。


好的,从问题中可以看出,它给出了小时的数字表示。同样适用于分钟。在那之后建立你的检查。

当前时间的问题可能是您使用的日历。它会自动将时间转换为您使用的日历时区中的时间。您还可以使用时区的字符串表示形式创建日历。我认为它在 NSCalendar 的 API 中。然后在你制作了那个日历之后,就用那个作为当前时间。

【讨论】:

  • 好吧,我可以这样做。但它仍然存在问题。请再次查看我在问题中的更新。
  • 不确定。我会接受你的回答,只是因为你帮助了我,但它仍然不起作用。哦,好吧!
【解决方案2】:

关于 NSDate 的关键之一是它在 GMT 中。总是。但是,当您记录它时,它会根据用户的语言环境进行打印。

现在,当你这样做时,

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

您只是提供有关小时、分钟以及上午/下午的信息。怎么知道时间属于哪一天。它通过默认为 01/01/1970 和基于用户区域设置的时区来填补这一信息不足。您确实提供了当前时间的时区信息,这些信息可能与用户的区域设置相同,也可能不同。

要解决此问题,您必须生成一个包含日落时间的日期和时区信息的字符串,并将其传递给具有正确格式的日期格式化程序以获取日期。我假设你必须有这个(否则你怎么知道那天是日落或日出时间?)。由于您知道该地点,因此您也应该能够获得时区信息。一旦您有了正确的信息来构建日期,您使用的每种比较方法都将起作用。

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 2017-06-11
    • 2017-03-03
    • 1970-01-01
    • 2020-05-03
    • 2012-02-18
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多