Apply UFormat to System.DateTime variable - powershell

I am trying to apply a specific format to a DateTime variable on Powershell, but I am finding it impossible.
This works fine:
>> Get-Time -UFormat "%Y%m%d-%h%M%S"
20210412-135938
But if I try to assign it to a variable and then do the formatting, I encounter an error, for example
$startDate=Get-Date -Year 2021 -Month 01 -Day 01 -Hour 11 -Minute 00 -Second 00
$startDate=$startDate.addHours(10)
$startDate=$startDate.addHours(23)
($startDate) -UFormat "%Y%m%d-%h%M%S"
Then I get an Token Uformat unexpected error.
Could someone throw some light as on how to get this formatting to work?
Thank you,

There are more ways of formatting a date that are more 'PowerShelly' then using UFormat:
use the .Net ToString() method:
(Get-Date).AddHours(10).ToString("yyyyMMdd-HHmmss")
use the -Format parameter of Get-Date:
$startDate = (Get-Date).AddHours(10)
Get-Date -Date $startDate -Format "yyyyMMdd-HHmmss"
or use the -f format operator:
'{0:yyyyMMdd-HHmmss}' -f (Get-Date).AddHours(10)

You can pass an existing [datetime] value to Get-Date's -Date parameter:
Get-Date -Date $startDate -UFormat "%Y%m%d-%h%M%S"

-UFormat switch belongs to the Get-Date commandlet. So you would use this syntax:
Get-Date ($startDate) -UFormat "%Y%m%d" for example.
And if I am interpreting what you "really" want in your date format string, you have incorrect case on the hour token.
"%Y%m%d-%h%M%S" Should be
Get-Date ($startDate) -UFormat %Y%m%d-%H%M%S
Which will return: 20210102-200000
These tokens - at least where I get them - are from TCL.
Goggle tcl clock manual page for a complete list.
I usually use -UFormat switch - I know TCL tokens and don't have to worry about escaping letters used in Microsoft date string tokens.
Get-Date ($startDate) -Format "Hello-yyyyMMdd-HHmmss-World"
returns: 20ello-20210102-200000-Worl2 because the H and d are tokens - and would need to be escaped \H \d
whereas
Get-Date ($startDate) -UFormat "Hello-%Y%m%d-%H%M%S-World"
returns: Hello-20210102-200000-World

Related

Powershell - Find the latest Friday

How can the following code be modified to identify the latest Friday within the past week (instead of the next one), but with formatting?
$Date = #(#(0..7) | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -ieq "Friday"})[0]
Source: https://stackoverflow.com/a/23939203/5651418
The post you linked to offers a more elegant solution, which you can adapt as follows:
# Get the most recent Friday relative to the given date,
# which may be that date itself.
$mostRecentFriday =
($date = Get-Date).AddDays((-7 - $date.DayOfWeek + [DayOfWeek]::Friday) % 7)
If you want to create a formatted string representation of the resulting [datetime] instance (all examples below yield something like '07 01 2022':
To use Unix-style format specifiers, use Get-Date's -UFormat parameter:
Get-Date $mostRecentFriday -UFormat '%d %m %Y'
To use .NET's format specifiers, use Get-Data's -Format parameter:
Get-Date $mostRecentFriday -Format 'dd MM yyyy'
Alternatively, pass the format string to the [datetime]
instance's .ToString() method:
$mostRecentFriday.ToString('dd MM yyyy')
If I understood correctly, your expected output would be 1 7 2022, I would personally use a do loop that stops as soon as the DayOfWeek Property of the DateTime instance is Friday:
$date = [datetime]::Now
do {
$date = $date.AddDays(-1)
} until($date.DayOfWeek -eq [DayOfWeek]::Friday)
$date.ToString("d M yyyy")
I noticed that some Get-Date -UFormat specifiers didn't seem to work when attempting to incorporate them into an output string.
Should anyone need to incorporate some rarely needed ones (like 'Week of Year' (%G), 'Day of Year (%j), etc) you could preset needed variables and add them to the output string:
$DayOfYear = (Get-Date -UFormat %j)
$WeekOfYear = (Get-Date -UFormat %V)
$Date = #(#(0..7) | % {$(Get-Date).AddDays(-$_)} | ? {$_.DayOfWeek -ieq "Wednesday"})[0].ToString("MM-dd-yyyy|Week $WeekOfYear|'Day' $DayOfYear")
I imagine someone could incorporate all the code into one Powershell command.
Additional Get-Date -UFormat specifiers: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-7.2#notes

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

Today and Yesterday's date at midnight in specific format

I need to get today and yesterdays date at midnight in the following format:
08/05/2018 00:00
The best I seem to be able to get is this:
get-date -Uformat "%D %R" -Hour 0 -Minute 00
08/05/18 00:00
I fail miserably when trying to get yesterday at midnight.
(Get-Date -UFormat "%s" -Hour 0 -Minute 00 -Second 00).AddDays(-1)
Method invocation failed because [System.String] does not contain a method named AddDays.
At line:1 char:1
+ (Get-Date -UFormat "%s" -Hour 0 -Minute 00 -Second 00).AddDays(-1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
To get a date(time) at midnight you can use :
(Get-Date).Date
Or
[datetime]::Today
To format it according to your requirement can be tricky if your current date format has a different separator (as is the case here).
> (get-date).Date.ToString('MM/dd/yyyy HH:mm')
08-05-2018 00:00
The .ToString() method overrides the separator; to take the slash literal you have to escape it with a backslash:
> (get-date).Date.ToString('MM\/dd\/yyyy HH:mm')
08/05/2018 00:00
Or use:
> (get-date).Date.ToString('MM/dd/yyyy HH:mm', [cultureinfo]::InvariantCulture)
08/05/2018 00:00
Code
(Get-Date).ToString("dd/MM/yyyy 00:00")
(Get-Date).AddDays(-1).ToString("dd/MM/yyyy 00:00")
You have to perform the AddDays to the date while it's still a date (and not a string that looks like a date).
Result
05/08/2018 00:00
04/08/2018 00:00
For American format
dd/MM/yyyy simply becomes MM/dd/yyyy
For today use [DateTime]::Today and format it with ToString()
[Datetime]::Today.ToString("dd/MM/yyyy HH:mm")
For Yesterday, just add AddDays(-1)
[Datetime]::Today.AddDays(-1).ToString("dd/MM/yyyy HH:mm")
You were on the right track with the -UFormat option:
Get-Date -Hour 0 -Minute 00 -UFormat "%m/%d/%Y %H:%M"
This produces the following output:
08/05/2018 00:00
The error you are seeing is due to the fact that you are invoking AddDays method over a string. To manipulate the date, you can do the following:
(Get-Date -Hour 0 -Minute 00).AddDays(-1) | Get-Date -UFormat "%m/%d/%Y %H:%M"
This will produce the desired output.
(Get-Date).AddDays(-1)|Get-Date -format "yyyyMMdd"

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.

Use UFormat to get unix time

I can use following to append a date to a text:
"Foo {0:G} Foo" -f (date) #returns "Foo 2009-12-07 15:34:16 Foo"
But I want the time in Unix format.
I can get it by date -UFormat %s, but can I use the same syntax?
When I use -UFormat %s I get 1260199855,65625, how do I remove the decimal?
[int](Get-Date -UFormat %s -Millisecond 0)
Here's how I do it:
$DateTime = (Get-Date).ToUniversalTime()
$UnixTimeStamp = [System.Math]::Truncate((Get-Date -Date $DateTime -UFormat %s))
Just cast the result to an int like so:
PS> [int][double]::Parse((Get-Date -UFormat %s))
1260172909
PS> "Foo {0:G} Foo" -f [int][double]::Parse((Get-Date -UFormat %s))
Foo 1260172997 Foo
Using the Parse method means the string is parsed "culture aware" such that the appropriate decimal separator character is recognized for the current culture. If you just cast directly, PowerShell uses the invariant culture which causes problems for any culture where decimal sep char is not a period.
I did this, rounded up
[System.Math]::Round((date -UFormat %s),0)
My solution:
(Get-Date -UFormat %s) -Replace("[,\.]\d*", "")
I would just truncate the decimal:
(date -UFormat %s).split('.')[0]
The answer should be in UTC. This should be good for embedding in Discord. See https://www.unixtimestamp.com "-uformat %s" does NOT convert to UTC in powershell 5.1 (but powershell 7 does). Only one other answer takes this into account, and not the accepted answer.
$unixtime = get-date '12/28/22 10pm' | % ToUniversalTime | get-date -uformat %s
"<t:$unixtime>"
<t:1672282800>
Alternative for UTC unix time:
[datetimeoffset]'12/28/22 10pm' | % ToUnixTimeSeconds
1672282800