265

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"

3
  • 7
    I actually wished this syntax worked. $date -format "yyyMMdd" is much more intuitive for formatting a single object than '{0:yyyyMMdd}' -f $date. Commented Jul 28, 2015 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 Commented Jan 22, 2020 at 19:08
  • 2
    @orad your comment does vastly more to explain the "{0:...}" syntax boilerplate than the top+accepted answer that suggests it. Thank you. (Your comment tells us that it's a special case of something that supports multiple things being formatted at once, which in turn lets us realize that we're looking at something far more general than just syntactic sugar for .ToString(...)... and that, combined with enough programming experience, we can guess that the format strings use zero-indexed references to the objects being interpolated, and use {} to wrap placeholders.) Commented Oct 6, 2022 at 5:47

14 Answers 14

333

The same as you would in .NET:

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

Or:

$DateStr = '{0:yyyyMMdd}' -f $Date

Note that you can have a format string that gets multiple objects. For example:

'From {0:M/d/yyyy} to {1:M/d/yyyy}' -f $Date, $Date.AddDays(7)
Sign up to request clarification or add additional context in comments.

6 Comments

Results in: You cannot call a method on a null-valued expression.
@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.
I want to +1 but the totally cryptic appearance of "0:" and wrapping "{...}" with no explanation is really offputting for me. Why are they there? what are they saying to PowerShell or to the "-f" operator or to [...]?
The #: prefixes relate to the -f parameter order. So you can recall the values in any order, or multiple times. In this example it is superfluous
@mtraceur I updated the answer to clarify formatting objects using multiple format tokens.
It would be useful if the original answer included $Date = date as the first line of code in the answer, which would avoid confusion for those of us a lot less familiar with PowerShell, and prevents the error message reported above by @Langdon
68

A simple and nice way is:

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

4 Comments

This was the only approach that didn't throw a null-valued expression error for me. Thanks.
Ummm, doesn't this return the date formatted as a 24-hour time or am I being too US-Centric???
It’s in any format you specify. Regardless of your place of origin.
This is a better answer as the others had issues for me
36

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?).

2 Comments

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.
Either put examples in or append your comments to the selected answer. IMO
32

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

1 Comment

I like this answer because it encourages us to explore possibilities.
23

One thing you could do is:

$date.ToString("yyyyMMdd")

1 Comment

Thanks I did this - bugs me that -format doesn't work though.
15

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.. :)

2 Comments

$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.
Well, yeah.. It's a String, that's why I named it dateStr.. :) OP was trying to format a date object to a String.
8

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")

Comments

7

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()"

1 Comment

Use this with "o" for "xml" style datetimes
6

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

Comments

6

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

powershell -Command (Get-Date).ToString('yyyy-MM-dd')

Comments

2

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.

1 Comment

why not just? [string]$oDate = '([system.string]::format('{0:yyyyMMddHHmmss}',(Get-Date)))
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."

Comments

0

I converted my dueDate string to a datetime then formatted it.

 [Datetime]::ParseExact($dueDate,'MM/dd/yyyy H:mm:ss',$null).ToString('MM/dd/yyyy') 

Comments

0

This in @orad Comment Jul 28, 2015 at 23:51 but I feel like it should be an answer as well:

$date = Get-Date 
'{0:yyyyMMdd}' -f $date

works.

Specifically 4-digit year, 0-padded 2-digit month and day. The 'M' specifier is capitalized for month to differentiate it from minute which is lowercase 'm'. 2 chars means 0-padded.

See "The following table describes the custom date and time format specifiers..." in this link: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings for more specifiers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.