How I troubleshooted incorrect output from Get-Date while using both AddDays() and -Format on it.
In one of my scripts I name my files using
yyyyMMdd
In that particular case I don't want to rely on the date of creation nor modification date.
NOTE: There's no solid reasoning behind that, I simply have chosen that design. Thanks to that I notice something worth sharing and there it is 😉
My expected output is the date from 30 days ago in the desired format. Format is saved in variable
$dateFormat
If you try to run any of these cmdlet's, they won't work:
$dateFormat = 'yyyyMMdd'
(Get-Date).AddDays(-30) -Format $dateFormat
(Get-Date -Format $dateFormat).AddDays(-30)
Let's break them down and see, why.
First option does the following, going step by step:
# Prerequisite - define date format
$dateFormat = 'yyyyMMdd'
# Gets current date
Get-Date
# Subtracts 30 days from the date
(Get-Date).AddDays(-30)
# Tries to specify the formatting
(Get-Date).AddDays(-30) -Format $dateFormat
If we run them step-by-step, only the last line fails. The error is:
At line:1 char:25
+ (Get-Date).AddDays(-30) -Format $dateFormat
+ ~~~~~~~
Unexpected token '-Format' in expression or statement.
At line:1 char:33
+ (Get-Date).AddDays(-30) -Format $dateFormat
+ ~~~~~~~~~~~
Unexpected token '$dateFormat' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
In simple English it says: you tried to specified
-Format
If we check it carefully, we might notice that we're trying to specify format to the output of
AddDays()
Get-Date
# We already have $dateFormat, no need to specify again
# $dateFormat = 'yyyyMMdd'
# Gets current date
Get-Date
# Convert it to the format specified
Get-Date -Format $dateFormat
# Tries to subtract 30 days
(Get-Date -Format $dateFormat).AddDays(-30)
As previously, the last line fails. This time with:
Method invocation failed because [System.String] does not contain a method named 'AddDays'.
At line:1 char:1
+ (Get-Date -Format $dateFormat).AddDays(-30)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Error message gives us pretty clear explanation why it fails, but where on earth did we use
[System.String]
The key is the
-Format
GetType()
PS> (Get-Date).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True DateTime System.ValueType
PS> (Get-Date -Format $dateFormat).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
String type doesn't have
AddDays
Get-Member
Get-Date -Format $dateFormat | Get-Member -Name AddDays
No suprise, nothing in output.
We already know what to do - use
AddDays()
DateTime
String
-Format
Let's do it in two steps
# We already have $dateFormat, no need to specify again
# $dateFormat = 'yyyyMMdd'
# Calculate desired date
$30DaysAgo = (Get-Date).AddDays(-30)
# Convert to DateTime and apply formatting
Get-Date -Date $30DaysAgo -Format $dateFormat
By having a quick look at the docs of Get-Date
-Date
Type: DateTime
Aliases: LastWriteTime
Position: 0
Default value: None
Accept pipeline input: True
Accept wildcard characters: False
We discover that we might skip
-Date
# Numbered position
Get-Date $30DaysAgo -Format $dateFormat
# Pipeline input
$30DaysAgo | Get-Date -Format $dateFormat
-Format
Get-Date
DateTime
String
DateTime
Get-Date
-Format
Date
Get-Date