NSDate - 偏移时区

发布于 2024-10-10 11:59:56 字数 3370 浏览 0 评论 0原文

我一定错过了她的一些小事,但无法弄清楚。尝试创建一个日期进行比较,但我似乎无法将 currentDate 从 GMT 偏移到 EST:

// current date (gmt) //
NSDate *currentDate = [NSDate date];

NSTimeZone *currentDateTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"EST"];

NSDateFormatter *currentDateFormat = [[NSDateFormatter alloc]init];
[currentDateFormat setTimeZone:currentDateTimeZone];
[currentDateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];

NSString *currentDateString = [currentDateFormat stringFromDate:currentDate];
NSLog(@"currentDateString: %@", currentDateString); // returns 2011-01-05 13:30:30 EST

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString];

NSLog(@"currentDateWithOffset: %@", currentDateWithOffset); // returns 2011-01-05 18:30:30 +0000

谢谢!

编辑:

我使用以下行调用一个单独的类中的方法(试图使其可移植):

[Expiration expires:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"] within:1.0]

在expires方法中,我有这些行:

NSComparisonResult comparison = [currentDateWithOffset compare:expires]; // check for a fixed date to disable the demo

double withinRange = [installDate timeIntervalSinceDate:currentDateWithOffset]; // check for number of seconds between "within" and the install date

然后我像这样比较这两个值:

if(withinRange >= within && withinRange > 0.0) {
    // app is expired //
}
else {
    // app is still enabled (so far...) //
    if(comparison == NSOrderedDescending || comparison == NSOrderedSame) {
        // app is expired //
    }
    else {
        // app is still enabled //
    }
}

这有帮助吗?感谢您的耐心等待!

编辑:

这是当前的整个 expires:within 方法...

+(BOOL)expire:(NSDate*)expires within:(double)within {
   // default expired value //
    BOOL expired = NO;

    // convert within value from days to seconds //
    within *= 24.0 * 60.0 * 60.0;

    // current date (gmt) //
    NSDate *currentDate = [NSDate date];

    // install date //
    NSDate *installDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"installDate"];

    // check for a value in installDate //
    if (nil == installDate) {
        // app is running for the first time //
        [[NSUserDefaults standardUserDefaults]setObject:currentDate forKey:@"installDate"];
        [[NSUserDefaults standardUserDefaults]synchronize];
        installDate = currentDate;
    }

    if([installDate timeIntervalSinceNow] < (-within)) {
        expired = YES;
    }
    else {
        if([expires timeIntervalSinceNow] < 0) {
            expired = YES;
        }
    }

    NSLog(@"installDate:%@", installDate);
    NSLog(@"expires:%@", expires);
    NSLog(@"currentDate:%@", currentDate);

    return expired; 
}

然后我从另一个类中调用它,

message.text = (YES == [Expiration expire:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 -0500"] within:(0.015625/2)]) ? @"This App is Expired" : @"This App is Active";

当在模拟器中运行时(新的应用程序安装),NSLog 显示了这个...

[Session started at 2011-01-06 10:43:46 -0500.]
2011-01-06 10:43:48.146 TimeBasedDemo[14717:207] installDate:2011-01-06 15:43:48 +0000
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] expires:2011-01-07 17:00:00 +0000
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] currentDate:2011-01-06 15:43:48 +0000

I must be missing something small her but can't figure it out. Trying to create a date for comparison, but I can't seem to offset currentDate from GMT to EST:

// current date (gmt) //
NSDate *currentDate = [NSDate date];

NSTimeZone *currentDateTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"EST"];

NSDateFormatter *currentDateFormat = [[NSDateFormatter alloc]init];
[currentDateFormat setTimeZone:currentDateTimeZone];
[currentDateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];

NSString *currentDateString = [currentDateFormat stringFromDate:currentDate];
NSLog(@"currentDateString: %@", currentDateString); // returns 2011-01-05 13:30:30 EST

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString];

NSLog(@"currentDateWithOffset: %@", currentDateWithOffset); // returns 2011-01-05 18:30:30 +0000

Thanks!

Edit:

I'm calling a method in a separate class (trying to make this portable) using the following line:

[Expiration expires:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"] within:1.0]

in the expires method, I have these lines:

NSComparisonResult comparison = [currentDateWithOffset compare:expires]; // check for a fixed date to disable the demo

double withinRange = [installDate timeIntervalSinceDate:currentDateWithOffset]; // check for number of seconds between "within" and the install date

I'm then comparing these two values like so:

if(withinRange >= within && withinRange > 0.0) {
    // app is expired //
}
else {
    // app is still enabled (so far...) //
    if(comparison == NSOrderedDescending || comparison == NSOrderedSame) {
        // app is expired //
    }
    else {
        // app is still enabled //
    }
}

Does this help? Thanks for your patience!

Edit:

Here's the entire expires:within method as it currently stands...

+(BOOL)expire:(NSDate*)expires within:(double)within {
   // default expired value //
    BOOL expired = NO;

    // convert within value from days to seconds //
    within *= 24.0 * 60.0 * 60.0;

    // current date (gmt) //
    NSDate *currentDate = [NSDate date];

    // install date //
    NSDate *installDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"installDate"];

    // check for a value in installDate //
    if (nil == installDate) {
        // app is running for the first time //
        [[NSUserDefaults standardUserDefaults]setObject:currentDate forKey:@"installDate"];
        [[NSUserDefaults standardUserDefaults]synchronize];
        installDate = currentDate;
    }

    if([installDate timeIntervalSinceNow] < (-within)) {
        expired = YES;
    }
    else {
        if([expires timeIntervalSinceNow] < 0) {
            expired = YES;
        }
    }

    NSLog(@"installDate:%@", installDate);
    NSLog(@"expires:%@", expires);
    NSLog(@"currentDate:%@", currentDate);

    return expired; 
}

I'm then calling it from another class with

message.text = (YES == [Expiration expire:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 -0500"] within:(0.015625/2)]) ? @"This App is Expired" : @"This App is Active";

When running in the simulator (fresh app install), NSLog displayed this...

[Session started at 2011-01-06 10:43:46 -0500.]
2011-01-06 10:43:48.146 TimeBasedDemo[14717:207] installDate:2011-01-06 15:43:48 +0000
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] expires:2011-01-07 17:00:00 +0000
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] currentDate:2011-01-06 15:43:48 +0000

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅忆 2024-10-17 11:59:56

这些答案都没有给我一个带有当前本地日期的 NSDate 对象。所以我是这样做的:

NSDate *currentDateWithOffset = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]];

None of these answers gave me an NSDate object with the current, local date. So here's how I did it:

NSDate *currentDateWithOffset = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]];
情栀口红 2024-10-17 11:59:56

NSDate 对象表示一个时刻,与时区和日历考虑无关。当您打印或解析日期时,时区信息是相关的,但它不存储在 NSDate 内。

假设您要这样创建到期日期:

NSDate *exp=[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"]

这表示您希望到期时间为 1 月 7 日中午 GMT。如果您希望它在美国东部时间中午到期,请改为使用 -0500 创建它。在进行比较时,您不应该做的就是弄乱当前时间。

查看时间是否已过的一个简单方法是

if ([exp timeIntervalSinceNow]<0) { /* it's expired */ }

,您可以查看自安装日期以来是否已过去within秒,如下所示:

if ([installDate timeIntervalSinceNow]<(-within)]) { /* it's expired */}

An NSDate object represents an instant in time irrespective of time zone and calendar considerations. Time zone info is relevant when you print or parse a date, but it is not stored within the NSDate.

Say you are creating your expiration date like this:

NSDate *exp=[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"]

That says you want the expiration to occur at noon GMT, on the 7th Jan. If you want it to expire at noon EST, create it with -0500 instead. What you should not have to do is mess with the current time when you do a comparison.

An easy way just to see if the time has passed is then

if ([exp timeIntervalSinceNow]<0) { /* it's expired */ }

and you can see if within seconds have passed since the install date like this:

if ([installDate timeIntervalSinceNow]<(-within)]) { /* it's expired */}
素食主义者 2024-10-17 11:59:56

在 Cocoa 中,NSDate 是未应用时区信息的日期的抽象表示。请注意,currentDateWithOffset 与日期字符串的日期相同,只是时区不同(提前五个小时)。这是预期的行为,因为 NSDate 不会保留用于创建它的时区。

In Cocoa, NSDate is an abstract representation of a date with no time zone information applied. Note that currentDateWithOffset is the same date as the date string, just in a different time zone (five hours ahead). This is expected behavior, as NSDate does not persist the time zone used to create it.

铜锣湾横着走 2024-10-17 11:59:56

我又做了一些修改,找到了一种“欺骗”偏移量的方法来满足我的需要。从其他阅读中,我猜测 NSCalendar 可能是一个更好的长期解决方案,但现在我最终更改

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString];

NSDate *currentDateWithOffset = [[NSDate alloc] initWithString:[NSString stringWithFormat:@"%@ +0000", currentDateString]];

这让我得到了我需要的结果,并且适用于我稍后使用的比较。感谢大家提供背景信息!

I tinkered around a bit more and found a way to 'cheat' the offset to suit my needs. From other reading, I'm guessing that NSCalendar might be a better long term-solution, but for now I ended up changing

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString];

to

NSDate *currentDateWithOffset = [[NSDate alloc] initWithString:[NSString stringWithFormat:@"%@ +0000", currentDateString]];

That got me the results I needed and works in the later comparisons I'm using. Thanks for the background info all!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文