ios – 知道什么时候使用短的或全月的名字

在iOS 7或8下,股票日历应用程序会执行一些我无法确定的事情.

在某些地区,如en_US,日历应用程序显示短(3个字母)的月份名称.

在其他语言环境(例如de_DE)下,日历应用程序会显示完整的月份名称.有趣的是,语言环境en_DE显示了短的月份名称,因此它似乎与区域格式的语言相关联.

我不知道的是如何知道使用哪个月份格式.

不管我的设备的区域设置,NSDateFormatter独立的ShortMonthSymbols给了我3个字母的月份名称,NSDateFormatter standaloneMonthSymbols给了我完整的月份名称.

也试过:

Nsstring *monthformat = [NSDateFormatter dateFormatFromTemplate:@"LLL" options:0 locale:[NSLocale currentLocale]];

并且为en_US和de_DE返回相同的LLL.

看NSLocale,似乎没有任何价值决定是使用短名称还是全名.

NSCalendar,NSDateFormatter或NSLocale中似乎没有什么可以帮助确定要使用哪个月份格式.

有谁有任何想法如何做出这样的决心?

更新:

我以为我找到了一个解决方案,但它并不适用于我尝试的所有地区.我使用各种语言环境运行以下代码,以查看是否可以在本地应用程序中显示短和长的月份名称的区域设置之间找到任何共同点:

NSLocale *locale = [NSLocale currentLocale];
Nsstring *Locid = [locale localeIdentifier];
NSLog(@"Locale = %@",Locid);

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSLog(@"monthSymbols = %@",[formatter monthSymbols]);
NSLog(@"shortMonthSymbols = %@",[formatter shortMonthSymbols]);
NSLog(@"veryShortMonthSymbols = %@",[formatter veryShortMonthSymbols]);
NSLog(@"monthStandalonesymbols = %@",[formatter standaloneMonthSymbols]);
NSLog(@"shortStandaloneMonthSymbols = %@",[formatter shortStandaloneMonthSymbols]);
NSLog(@"veryShortStandaloneMonthSymbols = %@",[formatter veryShortStandaloneMonthSymbols]);

NSDate *date = [NSDate date];
[formatter setDateStyle:NSDateFormatterShortStyle];
NSLog(@"short date style: %@",[formatter stringFromDate:date]);
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSLog(@"medium date style: %@",[formatter stringFromDate:date]);
[formatter setDateStyle:NSDateFormatterLongStyle];
NSLog(@"long date style: %@",[formatter stringFromDate:date]);
[formatter setDateStyle:NSDateFormatterFullStyle];
NSLog(@"full date style: %@",[formatter stringFromDate:date]);

[formatter setDateStyle:NSDateFormatterNoStyle];
[formatter setDateFormat:@"M"];
NSLog(@"M date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"MM"];
NSLog(@"MM date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"MMM"];
NSLog(@"MMM date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"MMMM"];
NSLog(@"MMMM date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"MMMMM"];
NSLog(@"MMMMM date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"L"];
NSLog(@"L date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"LL"];
NSLog(@"LL date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"LLL"];
NSLog(@"LLL date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"LLLL"];
NSLog(@"LLLL date format: %@",[formatter stringFromDate:date]);
[formatter setDateFormat:@"LLLLL"];
NSLog(@"LLLLL date format: %@",[formatter stringFromDate:date]);

我已经使用en_US,en_GB,es_ES,de_DE,fr_FR和it_IT进行了测试.法语和德语语言环境在日历应用程序中显示完整的月份名称,其余显示名称.

测试代码看起来很有希望的一件事是,只有法国和德国的地区在shortMonthSymbols的末尾有一段时间.

那么我运行以下代码来查找在短月份符号中使用标点符号的所有区域设置:

NSMutableArray *hasDot = [[NSMutableArray alloc] init];
NSMutableArray *nodot = [[NSMutableArray alloc] init];
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
NSArray *locales = [NSLocale availableLocaleIdentifiers];
for (Nsstring *Locid in locales) {
    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:Locid];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setLocale:locale];
    NSArray *shortNames = [formatter shortMonthSymbols];
    //NSLog(@"locale: %@,short names: %@",Locid,shortNames[10]);
    Nsstring *nov = shortNames[10];
    unichar char1 = [nov characteratIndex:0];
    unichar charN = [nov characteratIndex:nov.length - 1];
    if ([letters characterIsMember:char1] && [letters characterIsMember:charN]) {
        [nodot addobject:Locid];
    } else {
        [hasDot addobject:Locid];
    }
}

NSLog(@"no dot: %@",[nodot sortedArrayUsingSelector:@selector(compare:)]);
NSLog(@"has dot: %@",[hasDot sortedArrayUsingSelector:@selector(compare:)]);

通过结果扫描,我发现荷兰语区域在短月份的符号中使用了一段时间.但是,对日历应用程序的快速测试显示,当设备设置为荷兰语(nl_NL)时,日历应用程序会显示较短的月份名称.啊.

更新2:

我已经测试了几个地方.以下显示长月名:

fr_FR,ru_RU,sv_SE(实际上是每种语言的所有语言环境)

以下(和我确定更多)显示短的一个月:

en_US,it_IT,nl_NL,ca_ES,uk_UA,ro_RO(实际上是每种语言的所有语言环境)

解决方法

一旦经常,有一个值得研究的问题. Rick,对于我,我调试了日历应用程序(可以使用附加到MobileCal进程来完成).这一切都归结于EventKitUI`CurrentLocaleRequiresUnabbrevatedMonthNames,其中回答了所需的问题.

我们来看看它的反汇编:

EventKitUI`CurrentLocaleRequiresUnabbrevatedMonthNames:
0x102c6bec7:  pushq  %rbp
0x102c6bec8:  movq   %rsp,%rbp
0x102c6becb:  pushq  %r15
0x102c6becd:  pushq  %r14
0x102c6becf:  pushq  %rbx
0x102c6bed0:  subq   $0xb8,%rsp
0x102c6bed7:  movq   0x14a3aa(%rip),%r15      ; (void *)0x0000000104e93070: __stack_chk_guard
0x102c6bede:  movq   (%r15),%rax
0x102c6bee1:  movq   %rax,-0x20(%rbp)
0x102c6bee5:  cmpq   $0x0,0x1c01fb(%rip)      ; CurrentLocaleRequiresUnabbrevatedMonthNames.usesFullLengthMonthNames + 6
0x102c6beed:  je     0x102c6beff               ; CurrentLocaleRequiresUnabbrevatedMonthNames + 56
0x102c6beef:  movb   0x1c01eb(%rip),%al       ; CurrentLocaleRequiresUnabbrevatedMonthNames.hasChecked
0x102c6bef5:  xorb   $0x1,%al
0x102c6bef7:  testb  $0x1,%al
0x102c6bef9:  je     0x102c6c0d6               ; CurrentLocaleRequiresUnabbrevatedMonthNames + 527
0x102c6beff:  movq   0x1b583a(%rip),%rdi      ; (void *)0x00000001025dae58: NSLocale
0x102c6bf06:  movq   0x1aef23(%rip),%rsi      ; "currentLocale"
0x102c6bf0d:  movq   0x14a524(%rip),%r14      ; (void *)0x0000000104945000: objc_msgSend
0x102c6bf14:  callq  *%r14
0x102c6bf17:  movq   %rax,%rdi
0x102c6bf1a:  callq  0x102d29920               ; symbol stub for: objc_retainAutoreleasedReturnValue
0x102c6bf1f:  movq   %rax,%rbx
0x102c6bf22:  movq   0x14a227(%rip),%rax      ; (void *)0x00000001025a3cd8: NSLocaleLanguageCode
0x102c6bf29:  movq   (%rax),%rdx
0x102c6bf2c:  movq   0x1ae12d(%rip),%rsi      ; "objectForKey:"
0x102c6bf33:  movq   %rbx,%rdi
0x102c6bf36:  callq  *%r14
0x102c6bf39:  movq   %rax,%rdi
0x102c6bf3c:  callq  0x102d29920               ; symbol stub for: objc_retainAutoreleasedReturnValue
0x102c6bf41:  movq   %rax,%r14
0x102c6bf44:  movq   %rbx,%rdi
0x102c6bf47:  callq  *0x14a4f3(%rip)           ; (void *)0x00000001049429b0: objc_release
0x102c6bf4d:  movq   0x1c0194(%rip),%rdi      ; __languagesRequiringUnabbreviatedMonthNames
0x102c6bf54:  testq  %rdi,%rdi
0x102c6bf57:  jne    0x102c6c0b0               ; CurrentLocaleRequiresUnabbrevatedMonthNames + 489
0x102c6bf5d:  leaq   0x15425c(%rip),%rax      ; @"ru"
0x102c6bf64:  movq   %rax,-0xd0(%rbp)
0x102c6bf6b:  leaq   0x1524ce(%rip),%rax      ; @"de"
0x102c6bf72:  movq   %rax,-0xc8(%rbp)
0x102c6bf79:  leaq   0x154260(%rip),%rax      ; @"fr"
0x102c6bf80:  movq   %rax,-0xc0(%rbp)
0x102c6bf87:  leaq   0x154272(%rip),%rax      ; @"fi"
0x102c6bf8e:  movq   %rax,-0xb8(%rbp)
0x102c6bf95:  leaq   0x154284(%rip),%rax      ; @"pt"
0x102c6bf9c:  movq   %rax,-0xb0(%rbp)
0x102c6bfa3:  leaq   0x154296(%rip),%rax      ; @"no"
0x102c6bfaa:  movq   %rax,-0xa8(%rbp)
0x102c6bfb1:  leaq   0x1542a8(%rip),%rax      ; @"nb"
0x102c6bfb8:  movq   %rax,-0xa0(%rbp)
0x102c6bfbf:  leaq   0x1542ba(%rip),%rax      ; @"nn"
0x102c6bfc6:  movq   %rax,-0x98(%rbp)
0x102c6bfcd:  leaq   0x1542cc(%rip),%rax      ; @"sv"
0x102c6bfd4:  movq   %rax,-0x90(%rbp)
0x102c6bfdb:  leaq   0x1542de(%rip),%rax      ; @"he"
0x102c6bfe2:  movq   %rax,-0x88(%rbp)
0x102c6bfe9:  leaq   0x1542f0(%rip),%rax      ; @"th"
0x102c6bff0:  movq   %rax,-0x80(%rbp)
0x102c6bff4:  leaq   0x154305(%rip),%rax      ; @"hi"
0x102c6bffb:  movq   %rax,-0x78(%rbp)
0x102c6bfff:  leaq   0x15431a(%rip),%rax      ; @"bn"
0x102c6c006:  movq   %rax,-0x70(%rbp)
0x102c6c00a:  leaq   0x15432f(%rip),%rax      ; @"mr"
0x102c6c011:  movq   %rax,-0x68(%rbp)
0x102c6c015:  leaq   0x154344(%rip),%rax      ; @"ur"
0x102c6c01c:  movq   %rax,-0x60(%rbp)
0x102c6c020:  leaq   0x154359(%rip),%rax      ; @"te"
0x102c6c027:  movq   %rax,-0x58(%rbp)
0x102c6c02b:  leaq   0x15436e(%rip),%rax      ; @"ta"
0x102c6c032:  movq   %rax,-0x50(%rbp)
0x102c6c036:  leaq   0x154383(%rip),%rax      ; @"gu"
0x102c6c03d:  movq   %rax,-0x48(%rbp)
0x102c6c041:  leaq   0x154398(%rip),%rax      ; @"kn"
0x102c6c048:  movq   %rax,-0x40(%rbp)
0x102c6c04c:  leaq   0x1543ad(%rip),%rax      ; @"ml"
0x102c6c053:  movq   %rax,-0x38(%rbp)
0x102c6c057:  leaq   0x1543c2(%rip),%rax      ; @"ne"
0x102c6c05e:  movq   %rax,-0x30(%rbp)
0x102c6c062:  leaq   0x1543d7(%rip),%rax      ; @"pa"
0x102c6c069:  movq   %rax,-0x28(%rbp)
0x102c6c06d:  movq   0x1b55ec(%rip),%rdi      ; (void *)0x00000001025d9cd8: NSArray
0x102c6c074:  movq   0x1ae5cd(%rip),%rsi      ; "arrayWithObjects:count:"
0x102c6c07b:  leaq   -0xd0(%rbp),%rdx
0x102c6c082:  movl   $0x16,%ecx
0x102c6c087:  callq  *0x14a3ab(%rip)           ; (void *)0x0000000104945000: objc_msgSend
0x102c6c08d:  movq   %rax,%rdi
0x102c6c090:  callq  0x102d29920               ; symbol stub for: objc_retainAutoreleasedReturnValue
0x102c6c095:  movq   0x1c004c(%rip),%rdi      ; __languagesRequiringUnabbreviatedMonthNames
0x102c6c09c:  movq   %rax,0x1c0045(%rip)      ; __languagesRequiringUnabbreviatedMonthNames
0x102c6c0a3:  callq  *0x14a397(%rip)           ; (void *)0x00000001049429b0: objc_release
0x102c6c0a9:  movq   0x1c0038(%rip),%rdi      ; __languagesRequiringUnabbreviatedMonthNames
0x102c6c0b0:  movq   0x1ae6c1(%rip),%rsi      ; "containsObject:"
0x102c6c0b7:  movq   %r14,%rdx
0x102c6c0ba:  callq  *0x14a378(%rip)           ; (void *)0x0000000104945000: objc_msgSend
0x102c6c0c0:  movb   %al,0x1c001b(%rip)       ; CurrentLocaleRequiresUnabbrevatedMonthNames.usesFullLengthMonthNames
0x102c6c0c6:  movb   $0x1,0x1c0013(%rip)      ; __overlayCalendarGeneration + 7
0x102c6c0cd:  movq   %r14,%rdi
0x102c6c0d0:  callq  *0x14a36a(%rip)           ; (void *)0x00000001049429b0: objc_release
0x102c6c0d6:  movb   0x1c0005(%rip),%al       ; CurrentLocaleRequiresUnabbrevatedMonthNames.usesFullLengthMonthNames
0x102c6c0dc:  movq   (%r15),%rcx
0x102c6c0df:  cmpq   -0x20(%rbp),%rcx
0x102c6c0e3:  jne    0x102c6c0f3               ; CurrentLocaleRequiresUnabbrevatedMonthNames + 556
0x102c6c0e5:  addq   $0xb8,%rsp
0x102c6c0ec:  popq   %rbx
0x102c6c0ed:  popq   %r14
0x102c6c0ef:  popq   %r15
0x102c6c0f1:  popq   %rbp
0x102c6c0f2:  retq   
0x102c6c0f3:  callq  0x102d29a1c               ; symbol stub for: __stack_chk_fail

您可以看到,它创建一个需要未经缩短的月份名称的语言环境数组.然后,它将比较当前区域设置是否是这些区域设置之一.

代码中硬编码.

对于缩写月份,它使用LLL格式(如EventKitUI`CalStringForMonth所示),对于未缩短的月份,它使用LLLL格式(如EventKitUI`CalLongStringForMonth中所示).

干杯

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...