19

A simple & short question:

How can I setup a default date format in powershell like yyyy-mm-dd ? so any date output will be like this format?

or How to setup a date format globally in one script ?

Is there a way to output date only without time? when I output LastWriteTime, Default is

13-03-2014 14:51

I only need 13-03-2014, without the 14:51 part.

4 Answers 4

24

A date in PowerShell is a DateTime object. If you want a date string in a particular format, you can use the built-in string formatting.

PS C:\> $date = Get-Date
PS C:\> $date.ToString("yyyy-MM-dd")
2014-04-02

You can also use the string format (-f) operator:

PS C:\> "{0:yyyy-MM-dd}" -f $date
2014-04-02

The LastWriteTime property of a file is a DateTime object also, and you can use string formatting to output a string representation of the date any way you want.

You want to do this:

Get-ChildItem -Recurse \\path\ -filter *.pdf | Select-Object LastWriteTime,Directory

You can use a calculated property:

Get-ChildItem C:\Users\Administrator\Documents -filter *.pdf -Recurse |
  Select-Object Directory, Name, @{Name="LastWriteTime";
  Expression={$_.LastWriteTime.ToString("yyyy-MM-dd HH:mm")}}

Run

help Select-Object -Full

and read about calculated properties for more information.

Sign up to request clarification or add additional context in comments.

5 Comments

Here is what I need to do: gci -recu \\path\ -filter *.pdf | select LastWriteTime,Directory | export-csv \\path\000.csv how can I setup a $date in this?
Thank you for the hint, very useful, I will read the help for some basic concept.
This is ok, but I don't want to modify every line of date code to avoid the (weird, foreign, and confusing) US date format. Why PS doesn't default to the Windows date format is a bit beyond me.
Why would you need to modify every line of date code? (Remember, a DateTime is an object, not a string representation of a date/time.)
Nicely done; note that there's now a dedicated help topic for calculated properties: about_Calculated_Properties.
20

i've used this, it works for me, just copy it at the beginning of your script

$currentThread = [System.Threading.Thread]::CurrentThread
$culture = [CultureInfo]::InvariantCulture.Clone()
$culture.DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'
$currentThread.CurrentCulture = $culture
$currentThread.CurrentUICulture = $culture

in case you'll find problem in loading assembly for CultureInfo (i had this issue on Windows 2008 Server), change line 2 in this way

$currentThread = [System.Threading.Thread]::CurrentThread
$culture = $CurrentThread.CurrentCulture.Clone()
$culture.DateTimeFormat.ShortDatePattern = 'dd-MM-yyyy'
$currentThread.CurrentCulture = $culture
$currentThread.CurrentUICulture = $culture

7 Comments

Thank you - worked for me! I have used LongDatePattern.
This is more useful than having to use .ToString on every output line
Helpful, but you're addressing a different problem than what this question is about: You're answering how to redefine the current culture's formatting rules in a given script, without changing when these rules are applied. As of (at least) v5.1 of Windows PowerShell as well as in PowerShell (Core) 7, you can simplify to: $culture = [cultureinfo]::InvariantCulture.Clone(); $culture.DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'; [cultureinfo]::CurrentCulture = $culture.
You’re right, your approach is more general and works well in multi-threaded scripts or certain piping scenarios. However, you might consider rephrasing your comment. The wording you used: “to redefine the current culture's formatting rules in a given script, without changing when these rules are applied” is quite unclear. What exactly did you mean by that? I may be facing a language barrier, but I had a hard time understanding it, and I imagine other users (especially non-native English speakers) might struggle with it as well.
The OP's goal is to shorten the default stringification of [datetime] instances from 13-03-2014 14:51 to 13-03-2014. This suggests that the short-date pattern already is yyyy-MM-dd, and all they want is to make argument-less .ToString() calls use the d (short date) format instead of the default format, G. In other words: it isn't formats that need to be redefined, it is when the existing formats are to be applied.
a part of the fact that you answer is more correct in the sense that you replace "every" formatting, you reply that i'm a addressing a "different" problem doesn't make any sense to me, the problem is addressed by my answer and your answer in the same way, the difference is that I only replace the culture for the current thread while you modify the entire current culture that affects all the threads. your point "it isn't formats that need to be redefined, it is when the existing formats are to be applied." doesn't makes any sense to me, sorry i can't understand.
You're in effect redefining the short date format of the culture that is (put) in effect. Instead, my interpretation of what the OP is asking is: How do I make the default formatting of [datetime] instances a (short) date only, without the time-of-day component? The OP's current culture may be dd-MM-yyyy already, so this aspect - the specific short date format - may be incidental to their question, but I'll grant you that the phrasing of the second paragraph is somewhat ambiguous. Either way, our answers address different use cases; let's hope both are helpful to future readers.
14

for always usage you can add in your .\Documents\WindowsPowerShell\profile.ps1

$culture = (Get-Culture).Clone()
$culture.DateTimeFormat.ShortDatePattern = 'yyyy-MM-dd'
Set-Culture $culture

5 Comments

This is great for setting the format for all of your powershell sessions. This way you don't have to do it for each script or command and other users can still use their own format.
That's the best answer based on how the question has been written. I faced similar case that on my local computer I develop an azure function app which handling date format (key of my hashtable), but when i push in Azure it doesn't work because the function (Get-AzConsumptionUsageDetail) retrieves the date in US format on the function app, i will force the Culture on the function app, so i will be sure to het the date format as on my local computer.
I don't have this file on my computer, so I believe that the default date/time format is retrieved from somewhere else and can be overwritten by values in this particular PS1 file. Do you know where the default date/time format is written? Or is retrieved from some regional setting or so? (I'm working with Windows 10)
From what I can tell, this answer is ineffective: (a) due to not assigning to [cultureinfo]::CurrentCulture, the current session's culture remains unchanged (and even performing such an assignment will not work session-wide in Windows PowerShell, due to a bug / questionable design decision) and (b) Set-Culture - which persistently changes the culture but only affects future sessions - does not honor customized [cultureinfo] instances passed to it: only the culture name is honored, and that culture's standard definition is made the persistent one.
Note this impacts much more than just powershell.
1

Preface:

  • There's good information in some of the existing answers:

    • Bill Stewart's helpful answer is expanded on below.

    • Mosè Bottacini answer addresses a different problem: how to redefine the current / effective culture's formatting rules in a given script (without changing when they are applied).

    • Alban's answer is an - ineffective[1] - attempt to solve said different problem persistently, via code placed in a $PROFILE file.

  • The answer below applies as of v5.1 of Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and final version is 5.1) as well as to PowerShell (Core) 7.


Ad-hoc (on-demand) formatting of dates:

Is there a way to output date only without time?

Bill Stewart's helpful answer shows you how to use .NET APIs to format [datetime] (System.DateTime) instances using custom .NET date-time format strings; let me add that you can also use standard format strings: your desired date-only, numeric-only format can be requested with d, the short date format specifier; the following calls all output the dates in that format:

Get-Date -Format d
# equivalently:
(Get-Date).ToString('d')
# equivalently:
'{0:d}' -f (Get-Date)

# In the pipeline, using simplified syntax:
# Note: % is a built-in alias of the ForEach-Object cmdlet.
(Get-Item \).LastWriteTime | % ToString d

# In the pipeline, in the context of a calculated property:
# Note: 'select' is a built-in alias of the Select-Object cmdlet.
Get-Item . | 
  select Name, @{Name='LastWriteTime';Expression={$_.LastWriteTime.ToString('d')}}

Default formatting of dates:

There are two formatting scenarios to consider:

  • (a) When PowerShell outputs [datetime] instances directly, such as when calling Get-Date in isolation.

  • (b) When such instances are output indirectly, as properties of enclosing objects, such as the column / list values of objects (possibly implicitly) formatted with Format-Table / Format-List

    • In this case, [datetime] values are represented by their .ToString() method return values.

The following code, adapted from this answer, covers both (a) and (b) - however, as noted there, the solution does not cover the behavior inside "..." (string interpolation):

# Override .ToString() to use the short-date format.
Update-TypeData -Force -TypeName System.DateTime -MemberType ScriptMethod -MemberName ToString -Value {
  $this.ToString('d')
}
# Redefine .DateTime, so that the formatting system uses the overridden 
# .ToString() method too.
Update-TypeData -Force -TypeName System.DateTime -MemberType ScriptProperty -MemberName DateTime -Value {
  $this.ToString() # This calls the overridden .ToString() method.
}

Also, note that these definitions persist for the remainder of the current session.

If you'd like to make this behavior the default for all future PowerShell sessions, add the code to a relevant $PROFILE file.

Caveats:

  • Third-party code executed in your sessions may rely on the default formatting behavior.
  • It is trivial to bypass profile processing by passing the -NoProfile switch to PowerShell on startup (via its CLIs - powershell.exe for Windows PowerShell, pwsh for PowerShell (Core) 7)

[1] (a) Due to the code in the answer not assigning the customized cloned culture to [cultureinfo]::CurrentCulture, the current session's culture remains unchanged (and even performing such an assignment will not work session-wide in Windows PowerShell, due to a bug / questionable design decision - see this answer) and (b) Set-Culture - which persistently changes the culture but only affects future sessions - does not honor customized [cultureinfo] instances passed to it: only the culture name is honored, and that culture's standard definition is made the persistent one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.