在Windows 11的某些区域设置下,strptime无法正确处理Sep

编程语言 2026-07-08
txt <- c('Jan 1 2026 12:00AM', 'Feb 1 2026 12:00AM', 'Mar 1 2026 12:00AM',
         'Apr 1 2026 12:00AM', 'May 1 2026 12:00AM', 'Jun 1 2026 12:00AM',
         'Jul 1 2026 12:00AM', 'Aug 1 2026 12:00AM', 'Sep 1 2026 12:00AM',
         'Oct 1 2026 12:00AM', 'Nov 1 2026 12:00AM', 'Dec 1 2026 12:00AM')

strptime(txt, '%b%d%Y%I:%M%p')

这是一个与区域设置相关的问题。strptime 在MX Linux和 Windows 10上工作正常,但在Windows 11上并不总是可用,取决于区域设置。Windows 11(en-NZ 区域设置)版本现在在九月的Sep缩写上失效,但如果使用Sept而不是Sep的缩写则可以工作。这是一个区域设置相关的问题,也是Windows 11专属的问题。lubridate 对任一缩写都起作用。

解决方案

有资料称Windows 11 24H2更新将英语(新西兰)区域设置中的AbbreviatedMonthName(MMM)将九月的缩写从 "Sep" 改为 "Sept":

微软最近在Windows 11(24H2)和Server 2025中引入了一项变更,影响英语(新西兰)区域设置,具体将九月的缩写从 "Sep" 改为 "Sept"。此变更旨在与国际本地化标准(CLDR)保持一致,但这导致许多依赖传统 "Sep" 格式的现有系统出现兼容性问题。该更新影响跨多种应用的日期格式,包括使用dd-MMM-yyyy格式的POS、数据库和脚本。 这项缩写的更改将导致大多数依赖日期的POS功能出现严重问题,可能造成极端的数据丢失/损坏,甚至使POS完全不能运行。 1

当区域设置为NZ、使用MMM月份格式时,Windows Server 2025现在会得到 "Sept" 而不是 "Sep" 作为月份。这会在我们的旧软件中引发异常,因为需要特定的日期格式,在将格式化日期解析为SQL的 DateTime值时也会出错。
2

[为什么Windows 11 24H2更新将英语(新西兰) AbbreviatedMonthName(MMM)对九月从Sep改为Sept?](https://learn.microsoft.com/en-us/answers/questions/3953471/why-did-windows-11-24h2-update-change-english-(new)

Sep是九月的简短日期格式。有时 也是一个不错的读物。

Also ?strptime says about the parameter %b

Abbreviated month name in the current locale on this platform. (Also matches full name on input: in some locales there are no abbreviations of names.) Case-insensitive on input.

该平台当前区域设置中的缩写月份名称。(输入时也会与全名匹配:在某些区域设置中没有名称的缩写。)输入时不区分大小写。


我可以在 Windows 11 x64 (build 26100)

Sys.setlocale("LC_TIME", "en_NZ");  
# [1] "en_NZ"
strptime('Sep 1 2026 12:00AM', "%b %d %Y %I:%M%p")
# [1] NA
strptime('Sept 1 2026 12:00AM', "%b %d %Y %I:%M%p")
# [1] "2026-09-01 CEST"
format(as.Date("2026-09-01"), "%b")
# [1] "Sept"

Rstrptime.h 的代码中,在 b 情况下,区域设置缩写在这里获得:这里;在函数 get_locale_strings 中也在这里获得:这里

--> 记住这一点很重要:缩写月份名称会因区域设置和平台而异,即使在同一区域设置内,也会随着时间变化。

Windows 11 - MMM - 概览

loc <- c("en_GB", "en_US", "fr_FR", "de_DE", "en_KE", "en_AU", "en_NZ")
# system("locale -a", intern = TRUE) # for more options

sapply(loc, \(x) {
  Sys.setlocale("LC_TIME", x)
  format(seq(as.Date("2025-01-01"), by = "month", length.out = 12), "%b") |>
    iconv(from = "latin1", to = "UTF-8")
}) |> kableExtra::kbl(format = "pipe")
en_GB en_US fr_FR de_DE en_KE en_AU en_NZ
Jan Jan janv. Jan Jan Jan Jan
Feb Feb févr. Feb Feb Feb Feb
Mar Mar mars Mrz Mar Mar Mar
Apr Apr avr. Apr Apr Apr Apr
May May mai Mai May May May
Jun Jun juin Jun Jun Jun Jun
Jul Jul juil. Jul Jul Jul Jul
Aug Aug août Aug Aug Aug Aug
Sep Sep sept. Sep Sept Sep Sept
Oct Oct oct. Okt Oct Oct Oct
Nov Nov nov. Nov Nov Nov Nov
Dec Dec déc. Dez Dec Dec Dec

很遗憾,我无法在不同平台上进行测试。也许你可以来帮忙!

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章