Why does adding quotation changes the expression's value in Powershell? - powershell

I have just started to learn Powershell, and there is one thing I just can't wrap my head around. See below:
> Write-output $(Get-Date -DisplayHint Date)
//Expect: Tuesday, November 3, 2020
//Got: Tuesday, November 3, 2020
> Write-output "$(Get-Date -DisplayHint Date)"
//Expect: Tuesday, November 3, 2020
//Got: 11/03/2020 20:42:27
For the second line with quotation interpolation, can someone explain why it is showing a different format?
Thank you,

That's the default format for the ToString() method in the current culture. This output is the result of "turning it into a string". The following examples all result in similar output as they are converting to string.
Write-Host (converts the output to a string)
Write-Host (Get-Date -DisplayHint Date)
11/3/2020 11:46:00 PM
ToString()
(Get-Date -DisplayHint Date).ToString()
11/3/2020 11:48:55 PM
-as operator
(Get-Date -DisplayHint Date) -as [string]
11/03/2020 23:49:37
String interpolation
"{0}" -f (Get-Date -DisplayHint Date)
11/3/2020 11:51:27 PM
And of course you already discovered converting to string by enclosing in quotes.
If you want to control how it's formatted, here are a few ways.
(Get-Date).ToLongDateString()
Tuesday, November 3, 2020
(Get-Date).ToString("dddd, MMMM d, yyyy")
Tuesday, November 3, 2020
Get-Date -f "dddd, MMMM d, yyyy"
Tuesday, November 3, 2020

Date can be showed in a customised way when it is converted into string.
In the above code you have enclosed in double quotes, which powershell treats it as a string.
(Get-Date -DisplayHint Date).toString() may also give you same result.

Related

How convert a future date to the yyyy-mm-ddT00:00:00Z format with PowerShell

I am trying to get this to work in PowerShell with no success.
I would need to convert a future date and time (let's say July 1st 2022 midnight 00:00) to the format yyyy-mm-ddT00:00:00Z
The below command:
Get-Date -Format u
outputs to 2022-06-21 13:34:20Z (at the time of writing), which is pretty close to what i need for the present time.
Is there a way to get what i need without the use of regex or replace() method and also in the future?
The format is pretty flexible. Just specify it manually:
Get-Date -Format yyyy-MM-ddTHH:mm:ssZ
Output: 2022-06-21T03:51:17Z
For a future date, it's probably easier to create that in advance, then use it with the formatting:
$futuredate = (Get-Date).AddDays(30)
Get-Date $futuredate -Format "yyyy-MM-ddTHH:mm:ssZ"
Output: 2022-07-21T03:56:46Z
Or, if in your case you really do want exactly midnight for the day in question:
$futuredate = (Get-Date).AddDays(10).Date
Get-Date $futuredate -Format "yyyy-MM-ddTHH:mm:ssZ"
Output: 2022-07-01T00:00:00Z
Based on the above answer, i tried to come up with a version of getting the first day of the next month and the last day. Let me know your thoughts:
Beggining of month:
Get-Date -Format "yyyy-MM-ddT00:00:00Z" -Date ([datetime](Get-Date -Day 1).AddMonths(1))
Output: 2022-07-01T00:00:00Z
End of month:
Get-Date -Format "yyyy-MM-ddT23:59:59Z"-Date (([datetime](Get-Date -Day 1).AddMonths(2)).AddDays(-1))
Output: 2022-07-31T23:59:59Z

Unable to compare dates of different formats in PowerShell

I have to update objects in a data set by the last modified date.
The (potentially) updated objects come from a REST api call and the objects to be updated from a SharePoint list.
Unfortunately, I'm getting way different date/time formats for each identical item in PowerShell. Compare:
Rest call results: 2016-12-15T08:08:39.012+01:00
SharePoint list: Thursday, December 15, 2016 7:08:39 AM
I was thinking of using the [datetime]::ParseExact method but a) I don't know what the input format has to be and b) if that even helps me to compare the two afterwards.
I'd appreciate your help, thanks.
I'd like to address a few issues:
You can always use [System.DateTime]::Parse() for each of the formats. You don't need to use [System.DateTime]::ParseExact().
You can use Get-Date instead of C#. Use native features whenever possible. Get-Date $SomeDate will always give you the same results with [System.DateTime]::Parse($SomeDate).
The unnamed issue is one of the formats care about TimeZones but other one does not. You need to work on that.
you can store both the date in variable and change it to the specific format for example Get-Date $date -Format "yyyy-MM-dd hh:mm:ss" and then you can compare the dates for example
$date="Thursday, December 15, 2016 7:08:39 AM"
Get-Date $date -Format "yyyy-MM-dd hh:mm:ss"
$date="2016-12-15T08:08:39.012+01:00"
Get-Date $date -Format "yyyy-MM-dd hh:mm:ss"
for both output would be in same format
You can use Get-Date to convert the strings to [DateTime] objects, which can then be easily compared:
$date1 = Get-Date '2016-12-15T08:08:39.012+01:00'
$date2 = Get-Date 'Thursday, December 15, 2016 7:08:39 AM'
$date1 -gt $date2
True
$date1 -lt $date2
False
Thanks for the explanations, that was very helpful. I managed to compare and adjust for the timezone differences the following way:
$date1 = Get-Date '2016-12-15T08:08:39.012+01:00'
$date2 = (Get-Date 'Thursday, December 15, 2016 7:08:39 AM').AddHours(1)
By comparing the .DateTime property I will get the evaluation to be true:
$date1.DateTime -eq $date2.DateTime
True

Powershell Get-Date not formatting properly

I have a date I am reading from somewhere so I am retrieving as a string value. My Culture is de-DE but need the time to have the AM/PM for when the script runs in en-US:
$date = 10.04.2018 14:40:20
$NewDate = Get-Date -Date $date -Format "dd MMM yyyy h:mm:ss tt"
What I want is $NewDate to be 10 Apr 2018 2:40:20 PM but am only able to get 10 Apr 2018 2:40:20. In english the tt translates to an AM/PM just fine, but how do I get it here?
If you want to rely on a certain date string, no matter where and with what culture information your script is run, you have to define a fixed culture info for your output:
$date = '10.04.2018 14:40:20'
$culture = [System.Globalization.CultureInfo]::CreateSpecificCulture('en-US')
(Get-Date $date).ToString('dd MMM yyyy h:mm:ss tt', $culture)
Output:
10 Apr 2018 2:40:20 PM
The output will always be the same, even on your 'de-DE' machine. You can read more about date formatting in my answer here.
Look at this article, and adapt this code to achieve what you want.
$cultures = "en-US","en-GB","fr-CA","fr-FR","ms-MY","zh-HK", "de-DE"
foreach ($c in $cultures)
{
$culture = New-Object system.globalization.cultureinfo($c)
$date = get-date -format ($culture.DateTimeFormat.LongTimePattern)
New-Object psobject -Property #{"name"=$culture.displayname; "date"=$date}
}
Also be sure to look at the various properties of $culture.DateTimeFormat.
The $date variable is not a datetime type. Actually, this assignment will not run. I assume you meant to make it a string. Use ParseExact() to convert it to a date.
$date = [datetime]::ParseExact('10.04.2018 14:40:20','M.d.yyyy H:m:s', $null)
$NewDate = Get-Date -Date $date -Format "dd MMM yyyy h:mm:ss tt"

Display [datetime] object in 24 hour format

I have some code that checks for a valid date, simple example:
[datetime]::ParseExact(
'201809222130',
'yyyyMMddHHmm',
[System.Globalization.CultureInfo]::InvariantCulture
)
This outputs:
Saturday, September 22, 2018, 9:30:00 PM
I'm trying to display the hour in 24h format, desired output:
Saturday, September 22, 2018, 21:30:00 PM
It is possible to display 24h format using the Get-Date Cmdlet, e.g.: Get-Date -UFormat %R, but I can't use this when creating a [datetime] object.
How can I display 24h format?
There isn't any reason you can't use Get-Date with the [datetime] object your code creates. For example:
$d = [datetime]::ParseExact(
'201809222130',
'yyyyMMddHHmm',
[System.Globalization.CultureInfo]::InvariantCulture
)
Get-Date $d -UFormat %R
You could also use the .ToShortTimeString() method:
$d.ToShortTimeString()
Or .ToString and specify the tokens:
$d.ToString('HH:mm')
The PowerShell answer
Using get-date -format
HH is 24 hour
hh is 12 hour
get-date -format "yyyy-MM-dd HHmmss"
2021-04-12 183340
get-date -format "yyyy-MM-dd hhmmss"
2021-04-12 063340
Mark Wragg beat me to it!
To add to his answer, you are getting this output because of your region settings. On my machine, the same code returns:
22 September 2018 21:30:00
The reason for this is because my region settings look like this:
You could change your Global Region settings, but it's better to get it done with code.

powershell - how to Get-Date

I have the following
foreach($res in $result1)
{
$ed = $res.EVENT_DATE
}
$ed is
29 September 2015 00:00:00
(It comes out of a MySQL Database as '2015-09-29' - but I'm assuming powershell is being 'clever' and converting it).
However, I need it to display as '
2015-09-27
I tried:
$ed = $res.EVENT_DATE
$ed = get-date -date $ed
With the intention of then formatting it accordingly, But this gives me
Get-Date : Cannot bind parameter 'Date' to the target.
Exception setting "Date": "Object reference not set to an instance of an object."
What is the correct way of formatting this to display as required?
How Powershell displays it depends on your locale info.
For example:
D:\> get-date "29 September 2015 00:00:00"
Tuesday, September 29, 2015 12:00:00 AM
D:\> get-date "29 September 2015 00:00:00" -Format yyyy-MM-dd
2015-09-29
so you might try this:
foreach($res in $result1)
{
$ed = get-date $res.EVENT_DATE -format yyyy-MM-dd
}