【问题标题】:How To Localize a "Timer" on iPhone如何在 iPhone 上本地化“计时器”
【发布时间】:2010-11-05 20:04:00
【问题描述】:

我需要在 iPhone 上以“hh:mm:ss”格式显示计时器,但希望它本地化。例如,芬兰在时间分量 (hh.mm.ss) 之间使用句点而不是冒号。如果我正在处理“时间”,Apple 的 NSDateFormatter 可以解决问题,但我需要显示比 24 大得多的小时数。

我无法让 NSDate/NSDateFormatter 工作,因为当你用几秒钟制作一个时......

NSDate *aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTotalSeconds];

... 每 86,400 秒(一天的价值)NSDate 会自动增加一天,小时、分钟和秒会回到零。我需要让它在不翻转的情况下在任意秒数内工作。例如,我想在 86,401 秒时显示 24:00:01(或芬兰的 24.00.01)。

我的代码可以很好地管理总秒数,所以我唯一的问题是显示。一个简单的...

[NSString stringWithFormat:@"%d%@%d%@%d", hours, sepString, mins, sepString, secs]

... 如果我能找到一种方法来获取本地化的“sepString”(时间分量分隔符),那么它将起作用。 NSLocale 好像没有这个。

想法?

【问题讨论】:

  • 我不确定我是否理解这个问题,但您是否正在寻找分组分隔符?它使用NSLocaleGroupingSeparator 键入。请参阅此处的NSLocale 文档:developer.apple.com/library/ios/#documentation/Cocoa/Reference/…
  • @Justin:我认为分组分隔符是 10^3 个位置之间的标点符号,例如在美式英语中,逗号为 123,456,789。

标签: iphone ios


【解决方案1】:

这是一种获取任何语言环境的时间组件分隔符的公认方法。它应该适用于 iOS 3.2 及更高版本。我知道代码可以更简洁,但我打开了“最大冗长”标志以使其尽可能可读。

//------------------------------------------------------------------------------
- (NSString*)timeComponentSeparator
{
    // Make a sample date (one day, one minute, two seconds)
    NSDate *aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:((24*60*60)+62)];

    // Get the localized time string
    NSDateFormatter *aFormatter = [[NSDateFormatter alloc] init];
    [aFormatter setDateStyle:NSDateFormatterNoStyle];
    [aFormatter setTimeStyle:NSDateFormatterShortStyle];
    NSString *aTimeString = [aFormatter stringFromDate:aDate]; // Not using +localizedStringFromDate... because it is iOS 4.0+

    // Get time component separator
    NSCharacterSet *aCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@":-."];
    NSRange aRange = [aTimeString rangeOfCharacterFromSet:aCharacterSet];
    NSString *aTimeComponentSeparator = [aTimeString substringWithRange:aRange];    

    // Failsafe
    if ([aTimeComponentSeparator length] != 1)
    {
        aTimeComponentSeparator = @":";
    }

    return [[aTimeComponentSeparator copy] autorelease];
}
//------------------------------------------------------------------------------

【讨论】:

    【解决方案2】:

    这里是有关此主题的信息,供可能试图弄清楚世界不同地区使用什么字符来分隔时间分量的其他人使用。我检查了 iPhone 上的所有“区域格式”设置 - iOS 版本 4.1 (8B117),我发现除了七个区域外,所有区域都使用冒号 (hh:mm)。这是其他的(他们的 NSLocaleCountryCode 用花括号括起来)。

    使用句点,hh.mm

    • 丹麦语(丹麦){DK}
    • 芬兰语(芬兰){FI}
    • 塞尔维亚黑山(西里尔文){ME}
    • 塞尔维亚黑山(拉丁语){ME}
    • 塞尔维亚语(西里尔文){RS}
    • 塞尔维亚语(拉丁语){RS}

    使用破折号,hh-mm

    • 马拉地语(印度){IN}

    请注意,印度(不是马拉地语-印度)也有国家代码 IN,并且使用冒号。所以仅仅检查国家代码是不够的,你将不得不查看其他 NSLocale 字段。我还没有浏览所有领域,但我怀疑 NSLocaleScriptCode 或 NSLocaleVariantCode 可能会区分它们。这种复杂性是 Apple 应该在 SDK 中向我们公开这个字符的原因。我确实在 Radar 中记录了它,所以如果你同意,请也请求它,请求的数量对他们决定做什么很重要。

    【讨论】:

      【解决方案3】:

      在 iOS8 及更新版本中,您可以使用DateComponentsFormatter。下面是一个 Swift 3 示例。

      let duration: NSTimeInterval = 86401 // 24:00:01
      
      let formatter = DateComponentsFormatter()  
      formatter.unitsStyle = .positional  
      formatter.allowedUnits = [.hour, .minute, .second]  
      formatter.zeroFormattingBehavior = [.pad]
      
      let formattedDuration = formatter.string(from: duration)
      

      【讨论】:

        【解决方案4】:

        如果所有其他方法都失败,请查看使用 NSLocalizedString() 或 NSLocalizedStringWithDefaultValue。

        【讨论】:

        • 我不确定我是否理解NSLocalizedString() 的相关性。
        • 同意,NSLocalizedString 无济于事。有趣的是,时钟应用程序中的 Apple 定时器功能不会更改分隔符以匹配语言环境。
        • 在我看来,如果您在框架内找不到解决方案,您可以使用 NSLocalizedString() 作为分隔符。当然,它只是一个字符,但它会解决你的问题。
        • 这是要走的路。在 Localizable.strings 文件中为格式字符串创建一个字符串,然后为您要支持的每种语言创建格式字符串的一个版本。使用 NSLocalizedString() 获取用户当前语言的格式字符串的正确版本,并将该格式字符串作为第一个参数传递给 +[NSString stringWithFormat:]。然后你总能得到你想要的格式。
        • 您不能使用 NSLocalizedString 来执行此操作。在 iPhone 上,它仅适用于语言(不适用于语言环境)。日期格式差异与语言环境而非语言相关。语言是英语 (en)、法语 (fr) 等。语言环境是美国 (US)、英国 (GB) 等。由于某些原因,“en-GB”中的字符串在 iPhone 上不起作用。即使它确实有效,也有超过 240 个语言环境,我想支持它们。这就是 Apple 发明 NSLocale 的原因,我只是想看看我是否遗漏了什么,或者确实没有办法获得语言环境的时间组件分隔符。
        【解决方案5】:

        首先,您应该使用 NSDateFormatter 来格式化您的日期。 Apple 建议使用用户可以在设置中自定义的内置样式。以下代码直接来自苹果文档:

         NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
        
        [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
        
        [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
        
        NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:118800];
        
        NSString *formattedDateString = [dateFormatter stringFromDate:date];
        
        NSLog(@"formattedDateString for locale %@: %@",
        
                [[dateFormatter locale] localeIdentifier], formattedDateString);
        

        【讨论】:

        • 明白,但我没有显示日期,也没有显示时间(0:00 到 23:59)。我正在显示小时、分钟和秒。非常简单地说,如果计时器运行了 2 天 3 小时 4 分钟和 5 秒,我想显示 51:04:05 并且我希望它使用用户区域设置中的习惯格式。我想我会将时间分隔符硬编码为冒号并完成它,然后向 Apple 提出功能请求以获取区域设置的时间组件分隔符。
        • 对不起,应该更好地阅读这个问题!快速浏览了文档后,我没有看到直接本地化 TimeIntervals 的方法。假设 DateFormatter 确实使用了正确的分隔符,您可以使用它来找出适合您的语言环境的分隔符。这有点可怕,但至少在 iPhone 上进行了本地化设置。
        • 这是个好主意,谢谢。我检查了一下,NSDateFormatter 确实尊重 iOS 中的语言环境(区域),所以我可以从中获取字符。我认为使用 NSDateFormatterShortStyle 并解析第一个非数字字符的返回字符串将是执行此“hack”的最安全方法。即使 Apple 在 SDK 中添加了一种方法来获取时间分量分隔符,这也仅适用于最新版本,我仍然需要针对旧版本 iOS 的解决方案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 2011-06-29
        • 2011-03-08
        • 1970-01-01
        相关资源
        最近更新 更多