(Отвечая на мой собственный вопрос.)
Так называемая инвариантная культура в данном случае не так уж инвариантна. Это зависит как от версии вашей ОС, так и от региональных настроек текущего пользователя в ОС.
В терминах .NET интересующее вас свойство в календаре равно TwoDigitYearMax
, поэтому просмотрите CultureInfo.InvariantCulture.DateTimeFormat.Calendar.TwoDigitYearMax
или (new GregorianCalendar()).TwoDigitYearMax
. Документация по GregorianCalendar.TwoDigitYearMax
переопределению .
На компьютере под управлением Windows 10 версии 1809 («Обновление за октябрь 2018», «Redstone 5»), где пользователь не изменил региональные настройки (подробнее очто ниже), свойство TwoDigitYearMax
равно 2029
, и, как следствие, вы получите 25 декабря 19 35.
Но в Windows 10 версия 1903 («Обновление за май 2019»), «19H1»), то же свойство возвращает 2049
, поэтому ваш результат - 25 декабря 20 35.
Однако значение зависит не только от версии Windows. Также имеет значение то, что пользователь вводит в региональных настройках. Так что это на самом деле не «инвариант».
Вы можете изменить год среза на панели управления следующим образом:
- Нажмите Пуск , нажмите значок «шестеренка»слева (Настройки) и нажмите Время и язык .
- Нажмите Регион слева.
- Под Связанные настройки , нажмите Дополнительные дата, время и региональные настройки .
- (Вы находитесь в панели управления.) Нажмите Регион .
- (Вnew Region window.) Нажмите кнопку Дополнительные настройки ... в нижней части страницы, а в новом окне щелкните вкладку Date .
- In Календарь , настройте Когда вводится двузначный год, интерпретируйте его как год между .
В старых версиях Windows это может быть(вставлено из microsoft.com
):
- Нажмите Пуск , укажите Настройки , а затем нажмите Панель управления .
- Дважды щелкните Региональные настройки значок *.
- Перейдите на вкладку Дата .
- В При вводе двузначного года введите значение года в поле , введитетребуемый год, а затем нажмите OK .
. Или вы можете использовать реестр Windows напрямую, перейти к ключу HKEY_CURRENT_USER\Control Panel\International\Calendars\TwoDigitYearMax
и для каждого соответствующего "значения" в этомоставьте неизменным компонент name и отредактируйте компонент data значения (обычное десятичное представление строки) желаемого года среза. Если пользователь никогда не изменял этот параметр на панели управления, две самые внутренние клавиши (Calendars\TwoDigitYearMax
) еще не существуют. Применяются обычные предупреждения о смешивании с реестром.
После того, как вы изменили год в Панели управления, каждый процесс .NET, который запустился после внесения этих изменений, будет отражать ваш выбор вСвойство TwoDigitYearMax
достигнуто через InvarantCulture
!
Так что, если вам нужно согласованное поведение в разных версиях ОС и пользовательских настройках, я думаю, вы не можете использовать InvariantCulture
. Вместо этого может сработать что-то подобное:
var tmp = (CultureInfo)(CultureInfo.InvariantCulture.Clone());
tmp.DateTimeFormat.Calendar.TwoDigitYearMax = 2039; // any cutoff you need
// incorrect: tmp.Calendar.TwoDigitYearMax = 2039
var newInvariantCulture = CultureInfo.ReadOnly(tmp);
, а затем использовать этот экземпляр newInvariantCulture
всякий раз, когда вы анализируете даты с двухзначными годами (вы можете поместить его в какое-то поле static readonly
).
ПРЕДУПРЕЖДЕНИЕ: Каждый CultureInfo x
несет два различных Calendar
с, которые могут иметь разные двухзначные максимальные значения года, а именно:
x.DateTimeFormat.Calendar.TwoDigitYearMax
!=
x.Calendar.TwoDigitYearMax