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.