powershellcultureinfo

Get-Culture DateTimeFormat doesn't respect local setting in console, DOES in ISE


This will produce the correct European formatting on my VM configured for Netherlands, but only in the ISE.

(Get-Date).toString((Get-Culture).DateTimeFormat.ShortDatePattern)
(Get-Date).toString((Get-Culture).DateTimeFormat.ShortTimePattern)

24/01/2025
09:19

When I run it in the console via shortcut it reverts to US standard.

1/24/2025
9:24 AM

Is there something I am missing to ensure correct behavior in the console? Or just one more way that Microsoft's inconsistency makes me pull my hair out?

EDIT: Changed the title to better reflect the fact that the code ONLY works in the deprecated ISE, and fails in the console where one would expect it to work.

EDIT: An update for anyone else who runs into this mess. From the sounds of it I should NOT be seeing this behavior, but I am, which means I need to work around it because I have no idea if a customer machine will have the same problem. So, the solution is

$culture = (Get-ItemPropertyValue 'HKCU:\Control Panel\International' LocaleName)
[cultureinfo]::CurrentCulture = $culture
$startTime.ToString('d')
$startTime.ToString('t')

Where $startTime is a DateTime. So easy, and yet it seems to me that I shouldn't even need to concern myself with Culture. .ToString() should just return the correct format based on OS settings, and if I want to be a $^%# and ignore the user's settings I should have to work harder to force 'EN-US' on someone. /RANT


Solution

  • Preface:


    While there are many subtle and treacherous differences between the ISE and a regular Windows PowerShell console window / WT (Windows Terminal) tab, there is no appreciable difference with respect to culture handling.[1]

    However, there are culture-handling pitfalls that affect both environments:


    The upshot for your use case:

    Using Get-Culture isn't robust, as it isn't guaranteed to refer to the culture that is truly in effect if an in-session change was made.

    Therefore:

    & {
      [cultureinfo]::CurrentCulture = 'nl-NL'
      (Get-Date).ToString('d')  # 'd' == [cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
      (Get-Date).ToString('t')  # 't' == [cultureinfo]::CurrentCulture.DateTimeFormat.ShortTimePattern
    }
    

    Output:

    25-1-2025
    11:10
    

    [1] If you have a reproducible case, do tell us.
    There is a minor technical difference between these two environments, as iRon points out, but it doesn't seem to have any behavioral impact: in the ISE, Get-Culture returns an instance of a type that is derived from the expected [cultureinfo] type, namely [Microsoft.Windows.PowerShell.Gui.Internal.ISECultureInfo], which, as noted, can be discovered with (Get-Culture).pstypenames