Get the date modified to be formatted with AM/PM with powershell

Viewed 22228

I've currently got

Get-Item "C:\path\to\file.txt" | ForEach-Object { $_.LastWriteTime }

Which outputs like this

12/18/2018 16:54:32

But I want it to output like this

12/18/2018 4:54 PM

Is there any way I can do that?

4 Answers

Use the DateTime objects formatting. More info here

Get-Item "C:\path\to\file.txt" | ForEach-Object { 
  $_.LastWriteTime.ToString("MM/dd/yyyy hh:mm:ss tt")
}

Much simpler to just use (Get-Date -Format 'M/d/yyyy h:mm tt')

# Convert 24hr time to 12hr with AM/PM ie, Monday 01/03/22 12:01 PM

Get-Date -Format "HH" -OutVariable time >$2
if ($time -ge 12) {
    $ptime = Get-Date -Format "dddd MM/dd/yy hh:mm"
    Write-Host "Right now it is $ptime PM" 
} else {
    $atime = Get-Date -Format "dddd MM/dd/yy hh:mm"
    Write-Host "Right now it is $atime AM" 
}


#  clear variables

$time=$null
$atime=$null
$ptime=$null

tl;dr

Assuming that your current culture is US-English (in which case $PSCulture returns en-US), you have the following options to get the desired string format for a given [datetime] instance, such as contained in $_.LastWriteTime in your command ($PROFILE is used as a sample input file):

# Use .ToString() with the general date-time format, "g":
# -> e.g., "7/14/2022 3:44 PM"
Get-Item $PROFILE | ForEach-Object { 
  $_.LastWriteTime.ToString('g') 
}

# Alternative, via Get-Date -Format
Get-Item $PROFILE | ForEach-Object { 
  Get-Date -Date $_.LastWriteTime -Format g
}

Note that the above implies that the simplest way to get the current date and time in the desired format is to use:

# Get the *current* date and time in general format.
# -> e.g. "7/14/2022 12:47 PM"
Get-Date -Format g

If you need a custom format that isn't covered by one of the standard formats, use kpogue's helpful answer.

Read on for background information, including how to ask for formats from a different culture, notably how to use the en-US culture for formatting even while a different culture is in effect.


The command in your question would not produce the display format in your sample output - instead, it would result in a more verbose, culture-specific representation as you would see for the current date with Get-Date, such as Thursday, July 7, 2022 3:44:57 PM in the US-English culture.

However, you would get such output if you were to stringify the [datetime] value via string interpolation with "$($_.LastWriteTime)", in which case PowerShell invariably applies the invariant culture, which is based on the US-English culture, but distinct from it, notably in that it guarantees culture-invariance and long-term stability - specifically, in this case it differs with respect to 12-hour vs. 24-hour clock representations, in that it uses a 24-hour clock.

kpogue's helpful answer shows you how to use custom formatting to achieve the desired output format; however, given that it seems like you're interested in the standard (general) US-English date-time format, the following solution is simpler (using $PROFILE as a sample file name):

Standard date-time format specifier g produces the desired format:

# Assumes that the current culture is en-US
Get-Item $Profile | ForEach-Object {
  $_.LastWriteTime.ToString('g') 
}

Sample output:

7/7/2022 3:44:57 PM

If your current culture is not en-US, you can pass the culture to use for formatting explicitly, as the second argument:

# Works irrespective of what the current culture is.
Get-Item $Profile | ForEach-Object { 
  $_.LastWriteTime.ToString('g', [cultureinfo] 'en-US') 
}

This relies on the [datetime]::ToString() method having overloads that accept an [IFormatProvider] argument, which is an interface that the [cultureinfo] type implements, so that casting 'en-US' (the US-English culture's identifier) to [cultureinfo] results in that culture's general date-time format.

Related