【问题标题】:IOS NSDateFormatter ProblemsIOS NSDateFormatter 问题
【发布时间】:2012-07-17 10:38:38
【问题描述】:

我们正在构建一个需要在设备上存储条目的日期的应用程序,该应用程序将是国际化的,因此我们遇到了两个困境/挑战。

  1. 用户偏好

    如果用户选择 12 小时而不是 24 小时格式,我们会从 [NSDate date] 返回一个像这样的日期 2012-07-17 11:26:03 AM 在 SQLite 数据库中排序不是最佳的,因为我们不能将其存储为日期。

  2. 用户区域设置

    通常这没问题,但在 Blighty,我们有一个很棒的东西,叫做英国夏季。 10 月 25 日至 30 日一个周期增加一小时,3 月 25 日至 31 日一个周期减少一个小时,因此如果一年中有 8 个月不进行调整,则时间落后一小时。

我需要实现的是一个一致的日期,格式如下:2012-07-17 11:26:03,无论设备位于何处,还要考虑到 GMT+1 的位置。

任何帮助都会很棒。

编辑*

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm";
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT+01:00"];
[dateFormatter setTimeZone:gmt];
NSString *timeStamp = [dateFormatter stringFromDate:[NSDate date]];
NSDate *localDate = [dateFormatter dateFromString:timeStamp];


NSLocale* currentLocale = [NSLocale currentLocale]; 
NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
NSLog(@"Country Code: %@", countryCode);
NSLog(@"Current Loacle: %@", currentLocale);
if(([countryCode isEqualToString: @"GB"])){
    NSDate *mydate = [NSDate date];
    NSDate *fiddlyFoo = [mydate dateByAddingTimeInterval:3600];
    NSLog(@"Print GMT +1 %@",fiddlyFoo); 
} else {
    NSLog(@"Print GMT Local   %@",localDate); 
}

【问题讨论】:

    标签: ios datetime date nsdate nsdateformatter


    【解决方案1】:

    我现在正在做这样的事情。请注意,NSDate“知道”当前时区和夏令时等。所以您只需要以可排序的表示形式获取 GMT 版本的时间。我建议使用 RFC 3339,但您可以根据需要对其使用变体:

    这段代码:

    NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    
    // Create a local date for London, for testing purposes
    NSDateComponents *comps = [NSDateComponents new];
    [comps setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/London"]];
    [comps setDay:1];
    [comps setMonth:7];
    [comps setYear:2012];
    [comps setHour:14];
    NSDate *date = [gregorian dateFromComponents:comps];
    
    // Just want to show this date is 2PM in London July 1st
    NSDateFormatter *curFormat = [NSDateFormatter new];
    [curFormat setDateStyle:NSDateFormatterFullStyle];
    [curFormat setTimeStyle:NSDateFormatterFullStyle];
    NSLog(@"Reference date is good no: %@", [curFormat stringFromDate:date]);
    
    // So now we get the date as a rfc3339 string, referenced to GMT
    NSString *timeString;
    {
        NSDateFormatter *rfc3339 = [NSDateFormatter new];
        [rfc3339 setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
        rfc3339.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
        timeString = [rfc3339 stringFromDate:date];
    }
    // referenced to UTC (sortable with any other time), can save in SQL DB etc
    NSLog(@"Date as rfc3339 string: %@", timeString);
    
    // Now lets convert it back into a BST time
    NSDate *newDate;
    {
        NSDateFormatter *rfc3339 = [NSDateFormatter new];
        [rfc3339 setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
        rfc3339.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
        newDate = [rfc3339 dateFromString:timeString];
    
        // we want to show this as a string 2012-07-17 11:26:03
        NSDateFormatter *newFormatter = [NSDateFormatter new];
        [newFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; // local time
        [newFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/London"]];
    
        NSLog(@"Local string using 24 hour clock: %@", [newFormatter stringFromDate:newDate]);
    }
    

    生成这个输出,我相信这是你想要的:

    TimeTester[58558:f803] Reference date is good no: Sunday, July 1, 2012 9:00:00 AM Eastern Daylight Time
    TimeTester[58558:f803] Date as rfc3339 string: 2012-07-01T13:00:00Z
    TimeTester[58558:f803] Local string using 24 hour clock: 2012-07-01 14:00:00
    

    【讨论】:

    • 谢谢你,但是当我将字符串转换回日期时,我再次得到了我需要停止的 AM/PM 附录。我们需要它作为 NSDate,因为我们在应用程序的其他地方用它做一些事情
    • 好吧,上面的代码为您提供了一个可以排序的表示,它是基于 GMT 的。如果您需要将其转换为您想要呈现给用户的字符串,那么有一个反向编码可以为您提供 NSDate - 这就是您想要的吗?
    • 很抱歉,我的目标只是恢复 24 小时日期格式,无论时区或区域设置如何,但要针对 BST 进行调整
    • 很抱歉,如果我很密集,但如果您将时间以 UTC 时间保存在数据库中,一旦您拥有该时间,您就可以使用日期格式化程序将其更改为您想要的任何格式。如果您在手机上实时执行此操作,那么您实质上是在 iOS 上探测当前时区等并应用它。如果您尝试在设备上进行转换但不想使用设备的当前时区概念,您可以将格式化程序配置为使用您想要的任何时区。我想我只是不太明白你的目标是什么。
    • 看你给了我答案,但如果你仍然不明白,那么让我们继续。我可以尝试利用纽约的时间把一些东西放在一起,以更好地展示我想说的话。我在我的应用程序中使用上述技术首先将当前时间转换为纽约市当前时间,然后将该字符串转换为显示给世界任何地方的人的日期。一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2020-01-31
    • 2012-01-16
    相关资源
    最近更新 更多