MattMS
MattMS

Reputation: 53

How do I fix the date format In Powershell to use ISO 8601

I would like to change the default format of dates and times in Powershell to use the ISO 8601 format, so instead of displaying as dd/mm/yyyy, it would use yyyy-mm-dd

Please note: I do not want to have to specify anything on the date objects directly, as this will be annoying when there is a single date field on a returned object. I want to change the default formatting that will be used everywhere.

This is not answered by Windows ISO 8601 timestamp The answers there all involve working on the DateTime objects directly.

# NOT THIS
Get-Date -Format 'yyyy-mm-dd'

# NOR THIS
$d = Get-Date
$d.ToString('o')

The solution must work for Powershell 7 and above.

I have made the following attempts, but they both result in the errors shown.

Failed to set DateTimeFormat

(Get-Culture).DateTimeFormat = [cultureinfo]::InvariantCulture.DateTimeFormat

Output:

SetValueInvocationException: Exception setting "DateTimeFormat": "Instance is read-only."

Failed when calling Set-Culture

Set-Culture [cultureinfo]::InvariantCulture

Output:

Set-Culture: Cannot bind parameter 'CultureInfo'. Cannot convert value "[cultureinfo]::InvariantCulture" to type "System.Globalization.CultureInfo". Error: "Culture is not supported. (Parameter 'name')
[cultureinfo]::InvariantCulture is an invalid culture identifier."

Upvotes: 4

Views: 752

Answers (1)

Thomas
Thomas

Reputation: 422

(PowerShell 7.3.9)

My solution is to change the LongDatePattern and LongTimePattern of DateTimeFormat on current thread.

function Switch-DefaultTimeFormat {
    $culture = [CultureInfo]::InvariantCulture.Clone()

    # see https://learn.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo?view=net-7.0
    $culture.DateTimeFormat.LongDatePattern = "yyyy-MM-dd"
    $culture.DateTimeFormat.LongTimePattern = "HH:mm:ss.fff"

    # optional: `ShortDatePattern`, `ShortTimePattern`, `FullDateTimePattern` can be changed too:
    #   $culture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd"
    #   $culture.DateTimeFormat.ShortTimePattern = "HH:mm:ss.fff"
    #   $culture.DateTimeFormat.FullDateTimePattern = "yyyy-MM-dd_HH:mm:ss.fff"

    $currentThread = [System.Threading.Thread]::CurrentThread
    $currentThread.CurrentCulture = $culture
    $currentThread.CurrentUICulture = $culture
}

Call this function to apply the new default date format. Invoke the function from profile script to "make it the default".

See if it helps!

Test and output:

PS D:\> Get-Date

Tuesday, 14 November 2023 3:38:17 pm

PS D:\> Switch-DefaultTimeFormat
PS D:\> Get-Date

2023-11-14 15:38:17.838

Upvotes: 4

Related Questions