iPhone/Objective-C - 帮助解决 NSDateComponents 和 NSCalendar 与海外时区的问题

发布于 2024-11-06 00:00:12 字数 2446 浏览 0 评论 0原文

我使用下面的实用程序方法来显示过去的秒、分钟、小时等。

例如,1小时前,

我有一个朋友在海外测试我们的iPhone应用程序,每次他们提交一个项目时,该方法总是返回“1小时前”,因为新西兰领先2小时,而服务器托管在澳大利亚,这显然是2小时在后面。

直到我们的 SQL Server 赶上来;当项目日期开始正确计算时。

只是想知道如何处理时区差异并修改我的实用程序方法以在全球范围内工作?请随意帮助修改该方法,这样就不会出现太多代码行(如果您感到真的很无聊 - 并且慷慨)。

提前致谢。

+ (NSString *)elapsedTime:(NSDate *)date {
    NSUInteger desiredComponents = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

    NSDateComponents *elapsedTimeUnits = [[NSCalendar currentCalendar] components:desiredComponents
                                                                         fromDate:date
                                                                           toDate:[NSDate date]
                                                                          options:0];

    // Format to be used to generate string to display.
    NSString *scannedFormat = @"%d %@ ago";
    NSInteger number = 0;
    NSString *unit;

    if ([elapsedTimeUnits year] > 0) {
        number = [elapsedTimeUnits year];
        unit = [NSString stringWithFormat:@"year"];
    } else if ([elapsedTimeUnits month] > 0) {
        number = [elapsedTimeUnits month];
        unit = [NSString stringWithFormat:@"month"];
    } else if ([elapsedTimeUnits week] > 0) {
        number = [elapsedTimeUnits week];
        unit = [NSString stringWithFormat:@"week"];
    } else if ([elapsedTimeUnits day] > 0) {
        number = [elapsedTimeUnits day];
        unit = [NSString stringWithFormat:@"day"];
    } else if ([elapsedTimeUnits hour] > 0) {
        number = [elapsedTimeUnits hour];
        unit = [NSString stringWithFormat:@"hour"];
    } else if ([elapsedTimeUnits minute] > 0) {
        number = [elapsedTimeUnits minute];
        unit = [NSString stringWithFormat:@"minute"];
    } else if ([elapsedTimeUnits second] > 0) {
        number = [elapsedTimeUnits second];
        unit = [NSString stringWithFormat:@"second"];
    } else {
        number = 1;
        unit = @"second";
    }

    // Check if unit number is greater than 1, then append 's' at the end.
    if (number > 1) {
        unit = [NSString stringWithFormat:@"%@s", unit];
    }

    // Resultant string required.
    NSString *scannedString = [NSString stringWithFormat:scannedFormat, number, unit];

    return scannedString;
}

I use the below Utility method to display the seconds, minutes, hours, etc gone by.

e.g., 1 hour ago

I have a friend overseas testing our iPhone application and every time they submit an item the method always returns "1 hour ago" because New Zealand is 2 hours ahead and the server is hosted in Australia, which is obviously 2 hours behind.

It's only until our SQL Server catches up; when the item date starts to calculate properly.

Just wondering how I can handle time zone differences and modify my Utility method to work globally? Please feel free to help modify the method so it's not so many lines of code (if you're feeling really bored - and generous).

Thanks in advance.

+ (NSString *)elapsedTime:(NSDate *)date {
    NSUInteger desiredComponents = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

    NSDateComponents *elapsedTimeUnits = [[NSCalendar currentCalendar] components:desiredComponents
                                                                         fromDate:date
                                                                           toDate:[NSDate date]
                                                                          options:0];

    // Format to be used to generate string to display.
    NSString *scannedFormat = @"%d %@ ago";
    NSInteger number = 0;
    NSString *unit;

    if ([elapsedTimeUnits year] > 0) {
        number = [elapsedTimeUnits year];
        unit = [NSString stringWithFormat:@"year"];
    } else if ([elapsedTimeUnits month] > 0) {
        number = [elapsedTimeUnits month];
        unit = [NSString stringWithFormat:@"month"];
    } else if ([elapsedTimeUnits week] > 0) {
        number = [elapsedTimeUnits week];
        unit = [NSString stringWithFormat:@"week"];
    } else if ([elapsedTimeUnits day] > 0) {
        number = [elapsedTimeUnits day];
        unit = [NSString stringWithFormat:@"day"];
    } else if ([elapsedTimeUnits hour] > 0) {
        number = [elapsedTimeUnits hour];
        unit = [NSString stringWithFormat:@"hour"];
    } else if ([elapsedTimeUnits minute] > 0) {
        number = [elapsedTimeUnits minute];
        unit = [NSString stringWithFormat:@"minute"];
    } else if ([elapsedTimeUnits second] > 0) {
        number = [elapsedTimeUnits second];
        unit = [NSString stringWithFormat:@"second"];
    } else {
        number = 1;
        unit = @"second";
    }

    // Check if unit number is greater than 1, then append 's' at the end.
    if (number > 1) {
        unit = [NSString stringWithFormat:@"%@s", unit];
    }

    // Resultant string required.
    NSString *scannedString = [NSString stringWithFormat:scannedFormat, number, unit];

    return scannedString;
}

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

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

发布评论

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

评论(1

飘然心甜 2024-11-13 00:00:12

您需要使用 [NSTimeZone localTimeZone] 获取 iPhone 当前所在的时区,然后需要处理本地时间和服务器时间之间的差异。最安全的选择可能是在内部将所有时间转换为 GMT(特别是在向服务器提交时间时),然后在向用户显示时间时转换为本地时间。

您还可以使用“服务器时间”作为参考时区,确保您的应用程序知道(通过查询服务器或将其硬连接到您的应用程序中)该时区是什么,然后将所有时间值转换为“服务器时间” “在内部......但是如果您的服务器更改时区,或者当您的服务器启动和结束夏令时时出现一小时关闭的问题,这可能会遇到问题。

您还可以将时区存储为写入服务器的数据的一部分,但实际上这只是推迟了不可避免的事情:迟早您需要将这些时间转换为参考时区,以便您可以计算经过的时间。

You'll need to use [NSTimeZone localTimeZone] to get the time zone the iPhone is currently in, and then you'll need to handle the difference between local time and server time. The safest option is probably to convert all times to GMT internally (especially when submitting times to the server), and then convert to local time when displaying time to the user.

You could also use "server time" as a reference time zone, make sure your app knows (either by querying the server or hard-wiring it into your app) what that time zone is, and then convert all time values to "server time" internally... but that could run into problems if your server changes time zones, or off-by-an-hour issues when your server starts and ends Daylight Savings Time.

You could also store time zones as part of the data you're writing to the server, but really that's just putting off the inevitable: Sooner or later you'll need to convert these times to a reference time zone, so that you can calculate elapsed time.

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