如何在iPhone上本地化“计时器”

时间:2020-12-22 02:48:47

I need to display a timer in "hh:mm:ss" format on the iPhone, but want it localized. Finland, for example uses a period instead of a colon between the time components (hh.mm.ss). Apple's NSDateFormatter would do the trick if I was dealing with a "time" but I need to display hours much greater than 24.

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

I have not been able to make an NSDate/NSDateFormatter work because when you make one with seconds...

我无法使NSDate / NSDateFormatter工作,因为当你用秒制作一个...

NSDate *aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTotalSeconds];

... every 86,400 seconds (one day's worth) NSDate automatically increments the day and hours, minutes, and seconds go back to zero. I need to make it work on an any number of seconds without rolling over. For example, with 86,401 seconds I want to display 24:00:01 (or 24.00.01 in Finland).

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

My code manages total seconds fine, so the only problem I have is the display. A simple...

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

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

... would work if I could find a way to get at a localized "sepString" (the time component separator). NSLocale does not seem to have this.

...如果我能找到一种方法来获得本地化的“sepString”(时间组件分隔符),它将起作用。 NSLocale似乎没有这个。

Thoughts?

5 个解决方案

#1


3  

Here is a admittedly hackish way to get the time component separator for any locale. It should work on iOS 3.2 and above. I know the code can be more concise, but I turned my "maximum-verbosity" flag on to make it as readable as possible.

以下是为任何语言环境获取时间组件分隔符的一种公认的hackish方法。它应该适用于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


2  

Here is information on this topic for others who might be trying to figure out what character different areas of the world use to separate time components. I went through all of the "Region Format" settings on my iPhone - iOS version 4.1 (8B117) and I found all but seven regions use a colon (hh:mm). Here are the others (their NSLocaleCountryCode is in curly braces).

以下是有关此主题的信息,供其他可能试图弄清楚世界不同区域用于分隔时间组件的人物。我浏览了我的iPhone上的所有“区域格式”设置 - iOS版本4.1(8B117),我发现除了七个区域之外的所有区域都使用冒号(hh:mm)。这是其他的(他们的NSLocaleCountryCode是花括号)。

Use a period, hh.mm

• Danish (Denmark) {DK}
• Finnish (Finland) {FI}
• Serbian Montenegro (Cyrillic) {ME}
• Serbian Montenegro (Latin) {ME}
• Serbian (Cyrillic) {RS}
• Serbian (Latin) {RS}

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

Use a dash, hh-mm

• Marathi (India) {IN}

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

Note that India (not Marathi-India) also has the country code IN and it uses a colon. So just checking the country code is not enough, you will have to look at other NSLocale fields. I haven't gone through all the fields yet, but I suspect NSLocaleScriptCode or NSLocaleVariantCode might differentiate them. This complexity is why Apple should expose this character to us in the SDK. I did log it in Radar, so if you agree please request it too, quantity of requests matters a lot in what they decide to do.

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

#3


0  

If all else fails, look at using NSLocalizedString() or NSLocalizedStringWithDefaultValue.

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

#4


0  

First of all you should be using NSDateFormatter to format your dates. Apple recommends using the built-in styles available that the user can customize in the settings. The following code is straight from the apple docs:

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

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

#5


0  

In iOS8 and newer you can use DateComponentsFormatter. Below is a Swift 3 example.

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

#1


3  

Here is a admittedly hackish way to get the time component separator for any locale. It should work on iOS 3.2 and above. I know the code can be more concise, but I turned my "maximum-verbosity" flag on to make it as readable as possible.

以下是为任何语言环境获取时间组件分隔符的一种公认的hackish方法。它应该适用于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


2  

Here is information on this topic for others who might be trying to figure out what character different areas of the world use to separate time components. I went through all of the "Region Format" settings on my iPhone - iOS version 4.1 (8B117) and I found all but seven regions use a colon (hh:mm). Here are the others (their NSLocaleCountryCode is in curly braces).

以下是有关此主题的信息,供其他可能试图弄清楚世界不同区域用于分隔时间组件的人物。我浏览了我的iPhone上的所有“区域格式”设置 - iOS版本4.1(8B117),我发现除了七个区域之外的所有区域都使用冒号(hh:mm)。这是其他的(他们的NSLocaleCountryCode是花括号)。

Use a period, hh.mm

• Danish (Denmark) {DK}
• Finnish (Finland) {FI}
• Serbian Montenegro (Cyrillic) {ME}
• Serbian Montenegro (Latin) {ME}
• Serbian (Cyrillic) {RS}
• Serbian (Latin) {RS}

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

Use a dash, hh-mm

• Marathi (India) {IN}

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

Note that India (not Marathi-India) also has the country code IN and it uses a colon. So just checking the country code is not enough, you will have to look at other NSLocale fields. I haven't gone through all the fields yet, but I suspect NSLocaleScriptCode or NSLocaleVariantCode might differentiate them. This complexity is why Apple should expose this character to us in the SDK. I did log it in Radar, so if you agree please request it too, quantity of requests matters a lot in what they decide to do.

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

#3


0  

If all else fails, look at using NSLocalizedString() or NSLocalizedStringWithDefaultValue.

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

#4


0  

First of all you should be using NSDateFormatter to format your dates. Apple recommends using the built-in styles available that the user can customize in the settings. The following code is straight from the apple docs:

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

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

#5


0  

In iOS8 and newer you can use DateComponentsFormatter. Below is a Swift 3 example.

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