206

I can format the Get-Date cmdlet no problem like this:

$date = Get-Date -format "yyyyMMdd"

But once I've got a date in a variable, how do I format it? The statement below

$dateStr = $date -format "yyyMMdd"

returns this error:

"You must provide a value expression on the right-hand side of the '-f' operator"

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Ev.
  • 6,669
  • 13
  • 51
  • 85
  • 3
    I actually wished this syntax worked. `$date -format "yyyMMdd"` is much more intuitive for formatting a single object than `'{0:yyyyMMdd}' -f $date`. – orad Jul 28 '15 at 23:51
  • As an aside: PowerShell has an `-f` operator (with the syntax as shown in the accepted answer), but no `-format` operator. The error message is complaining about `ormat` not being a valid RHS operand, but note that recent PowerShell versions actually emit a different, more helpful error message: `Unexpected token '-format' in expression or statement` – mklement0 Jan 22 '20 at 19:08

12 Answers12

282

The same as you would in .NET:

$DateStr = $Date.ToString("yyyyMMdd")

Or:

$DateStr = '{0:yyyyMMdd}' -f $Date
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Josh
  • 66,410
  • 14
  • 139
  • 154
  • 1
    Results in: `You cannot call a method on a null-valued expression.` – Langdon Jun 03 '21 at 11:28
  • 1
    @Langdon - Assuming you are using the form $Date.ToString(...) then that error is because your $Date variable contains Null. You'll need to make sure you've actually assigned a DateTime value to it before calling ToString. ... The second form (using the -f operator) appears to tolerate nulls and will simply output an empty string. – Daniel Scott Aug 08 '21 at 02:21
32

The question is answered, but there is some more information missing:

Variable vs. Cmdlet

You have a value in the $Date variable and the -f operator does work in this form: 'format string' -f values. If you call Get-Date -format "yyyyMMdd" you call a cmdlet with some parameters. The value "yyyyMMdd" is the value for parameter Format (try help Get-Date -param Format).

-f operator

There are plenty of format strings. Look at least at part1 and part2. She uses string.Format('format string', values'). Think of it as 'format-string' -f values, because the -f operator works very similarly as string.Format method (although there are some differences (for more information look at question at Stack Overflow: How exactly does the RHS of PowerShell's -f operator work?).

DixonD
  • 6,317
  • 5
  • 29
  • 51
stej
  • 27,607
  • 11
  • 68
  • 102
  • 5
    What he is saying is that the -Format parameter causes Get-DateTime to return a string, not a DateTime object. So your variable $Date can no longer be formatted as expected. I REALLY wish the the -Format parameter would simply change the default behavior of a particular DateTime object's ToString method. Then it would work as you had expected. – Nathan Hartley Feb 02 '12 at 16:01
  • Either put examples in or append your comments to the selected answer. IMO – Mike Q Sep 29 '21 at 13:05
30

A simple and nice way is:

$time = (Get-Date).ToString("yyyy:MM:dd")

Stephen
  • 729
  • 8
  • 16
22

A very convenient -- but probably not all too efficient -- solution is to use the member function GetDateTimeFormats(),

$d = Get-Date
$d.GetDateTimeFormats()

This outputs a large string-array of formatting styles for the date-value. You can then pick one of the elements of the array via the []-operator, e.g.,

PS C:\> $d.GetDateTimeFormats()[12]
Dienstag, 29. November 2016 19.14
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
davidhigh
  • 13,407
  • 1
  • 37
  • 70
20

One thing you could do is:

$date.ToString("yyyyMMdd")
davidhigh
  • 13,407
  • 1
  • 37
  • 70
John Weldon
  • 38,339
  • 11
  • 92
  • 126
8

Do this if you absolutely need to use the -Format option:

$dateStr = Get-Date $date -Format "yyyMMdd"

However

$dateStr = $date.toString('yyyMMdd')

is probably more efficient.. :)

mklement0
  • 312,089
  • 56
  • 508
  • 622
tplive
  • 607
  • 10
  • 15
  • `$dateStr = (Get-Date $date -Format "yyyMMdd")` results in an object type that is different from a datetime object. Try playing around with this `$dateStr = [datetime](Get-Date $date -Format "yyyMMdd")` You'll see the difference right away. – Jamie Marshall Sep 07 '17 at 20:03
  • 1
    Well, yeah.. It's a String, that's why I named it dateStr.. :) OP was trying to format a date object to a String. – tplive Sep 10 '17 at 10:05
5

Very informative answer from @stej, but here is a short answer: Among other options, you have 3 simple options to format [System.DateTime] stored in a variable:

  1. Pass the variable to the Get-Date cmdlet: Get-Date -Format "HH:mm" $date

  2. Use toString() method: $date.ToString("HH:mm")

  3. Use Composite formatting: "{0:HH:mm}" -f $date

Eddie Kumar
  • 893
  • 12
  • 16
5

For anyone trying to format the current date for use in an HTTP header use the "r" format (short for RFC1123) but beware the caveat...

PS C:\Users\Me> (get-date).toString("r")
Thu, 16 May 2019 09:20:13 GMT
PS C:\Users\Me> get-date -format r
Thu, 16 May 2019 09:21:01 GMT
PS C:\Users\Me> (get-date).ToUniversalTime().toString("r")
Thu, 16 May 2019 16:21:37 GMT

I.e. Don't forget to use "ToUniversalTime()"

Peter L
  • 2,498
  • 1
  • 27
  • 30
5

I needed the time and a slight variation on format. This works great for my purposes:

$((get-date).ToLocalTime()).ToString("yyyy-MM-dd HHmmss")

2019-08-16 215757

According to @mklement0 in comments, this should yield the same result:

(get-date).ToString("yyyy-MM-dd HHmmss")
THE JOATMON
  • 16,761
  • 34
  • 110
  • 200
4

If you got here to use this in cmd.exe (in a batch file):

powershell -Command (Get-Date).ToString('yyyy-MM-dd')
mklement0
  • 312,089
  • 56
  • 508
  • 622
Jaroslav Záruba
  • 4,486
  • 4
  • 36
  • 54
0

You could just use this to select the format you want and then past it wherever it is needed.

$DTFormats = (Get-Date).GetDateTimeFormats()
$Formats = @()
$i=0
While ($i -lt $DTFormats.Count){
    $row = [PSCustomObject]@{
        'IndexNumber' = $i
        'DateTime Format' = $DTFormats[$i]
    }
    $Formats += $row
    $i++
}

$DTSelection = ($Formats | Out-GridView -OutputMode Single -Title 'Select DateTime Format').IndexNumber
$MyDTFormat = "(Get-Date).GetDateTimeFormats()[$DTSelection]"
Write-Host " "
Write-Host " Use the following code snippet to get the DateTime format you selected:"
Write-Host "    $MyDTFormat" -ForegroundColor Green
Write-Host " "
$MyDTFormat | Clip
Write-Host " The code snippet has been copied to your clipboard. Paste snippet where needed."
0

Format Date Time to your Output Needs

If you want to format the date and assign the string to a variable. I have combined both PowerShell and .NET to provide the flexibility.

    $oDate = '{0}' -f ([system.string]::format('{0:yyyyMMddHHmmss}',(Get-Date)))

How this Works

  • PowerShell Operator - '{0}' -f (.....)
  • .NET Notation - [system.string]::format('customformat',InputObject)
  • Customised Format by combining PowerShell with .NET - '{0:yyyyMMddHHmmss}'
  • Input Object provided by PowerShell cmdlet - (Get-Date)
  • Stored in the PowerShell variable - $oDate

Example

If the date and time when run was Monday, 5 July 2021 5:45:22 PM (Format '{0:F}').

  • $oDate = 20210705174522

Using the Code

You can customise the the string to meet your requirements by modifying 'yyyMMddHHmmss' using the Microsoft .NET Custom Date Time Notation.

TerryV
  • 1