Why does Windows Powershell represent datetime values in 24h format when using string interpolation?

McDonald, Matthew 221 Reputation points
2025-01-04T01:48:19.5333333+00:00

Edit: for clarity. Initial example was potentially confusing.


Why does Windows Powershell output datetime values in 24h format when using string interpolation but follows my culture settings and outputs as 12h when referencing it explicitly?

I'm using string interpolation due to needing the datetime to be output to a file.

I know I can manually format myself, but I'm just looking for an understanding of why and/or what makes this happen. I assume this is by design and I know Powershell has formatting rules that is likely contributing to this, but I'm interested specifically where those rules are defined.

Further based on other research and replies here, I'm being told that interpolation implicitly calls the .ToString() method. If that's the case, I'd expect calling .ToString() explicitly to produce the same result, but it does not.

I'm trying to get a concrete understanding of what is happening here. I'm not looking for a solution of how to get the format I need. I know how to do that.

For example:

PS C:\Users\xxxxxx> $newObject = [PSCustomObject]@{
>> CreateDate = Get-Date
>> }

PS C:\> $newobject
Created
-------
1/6/2025 8:50:18 PM    #<---- Expected 12h format. Note: EST timezone.

PS C:\Users\xxxxxx> $newObject.CreateDate
Friday, January 3, 2025 8:41:15 PM  #<---- why long format?

PS C:\Users\xxxxxx> "$($newObject.CreateDate)"
01/03/2025 20:41:15   #<---- why 24h format and dual mm/dd?

PS C:\Users\xxxxxx> $newObject.CreateDate.ToString()
1/3/2025 8:41:15 PM   #<---- why 12h AM/PM format and single m/d?
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,725 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Marcin Policht 31,315 Reputation points MVP
    2025-01-04T03:54:10.9+00:00

    When you use string interpolation, PowerShell implicitly calls the .ToString() method on the $newDate object. The default behavior of .ToString() is influenced by the formatting rules of the current culture settings, but when the object is a DateTime, it also adheres to the general formatting rules for that type. In this case, PowerShell defaults to using the ISO 8601 format (which includes a 24-hour time format) for DateTime objects when used in string interpolation. As far as I can tell, this is a performance optimization, as string interpolation is expected to produce a quick and simple output, often for logs or file writing, where precise control over formatting is not always needed. In addition, string interpolation aims for consistency in scenarios like logging and file outputs, where the 24-hour format might be more practical for sorting and consistency across time zones.

    When you just output $newDate without string interpolation, PowerShell uses a more user-friendly format, typically respecting the culture and regional settings of your system. For example, it defaults to a 12-hour time format (e.g., "8:41:15 PM") if you're in a locale that uses the 12-hour clock.

    When you call .ToString(), PowerShell also uses the default format for the DateTime object, which can vary based on the culture settings. In your case, the culture settings (likely en-US) are being honored, and it outputs the date in the 12-hour format (e.g., "1/3/2025 8:41:15 PM").

    The formatting behavior is influenced by the underlying .NET framework and the DateTime formatting rules. You can explicitly check the culture and formatting settings in PowerShellby running: powershell [System.Globalization.CultureInfo]::CurrentCulture This will show the current culture settings, including the time format conventions.

    The DateTime format in .NET can be customized or checked via the DateTimeFormatInfo object. To see how DateTime objects are formatted, you can use: powershell [System.Globalization.DateTimeFormatInfo]::CurrentInfo Obviously you can control the format explicitly by manually specifying the format:

       "$($newDate.ToString('yyyy-MM-dd HH:mm:ss'))"
    

    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin


  2. Rich Matheisen 47,496 Reputation points
    2025-01-05T19:40:18.7033333+00:00

    I think the "why" part of the question is one that's commonly overlooked.

    PowerShell is built around "object" and "streams".

    The $newDate looks like it simply transforms itself to the string "Friday, January 3, 2025 8:41:15 PM", but it isn't as simple as that. Because the result your running "$newdate", by itself, is not assigned (or "consumed") by a variable it's sent into the stream named "Success". Because that stream is not sent ("piped") into some other pipeline it's understood to be sent to the "host" (i.e., displayed on the screen). The host receives the object (which is not a string) and looks for a format file associated with the object type it receives. If one is found the host follows the instructions it contains to create the output it sends to the screen.

    Variable interpolation doesn't involve the host at all.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.