在Windows 11的某些区域设置下,strptime无法正确处理Sep
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 |
很遗憾,我无法在不同平台上进行测试。也许你可以来帮忙!