Subtracting time in powershell - powershell

I use the following time code:
$time = [DateTime]::UtcNow | get-date -Format "yyyyMMddHH"
$m2=$time-02 # trying to subtract 2 hours
However, for times like 2021021701, subtracting 2 gives me 2021021699. How can I have the time display in the correctly?

Another way. The 2nd arg can be a datetime or a timespan. $time is a datetime.
$time = get-date
$m2 = $time - [timespan]'2:0'
$m2
Wednesday, February 17, 2021 7:31:59 PM

To perform date calculations, operate on [datetime] (System.DateTime) instances and use that type's methods, such as .AddHours(); only after that should you create the desired string representation:
# Get the current UTC time as a [datetime] instance.
$time = [DateTime]::UtcNow
# Subtract 2 hours.
$m2Time = $time.AddHours(-2)
# Create the desired string representation.
$m2 = Get-Date $m2Time -Format 'yyyyMMddHH'

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

Date time format in PowerShell returning incorrect date in powershell

I want to change text 11.30 to time format 11:30 using [datetime] in powershell
$Stime = "11.30"
$time = "{00:hh:mm}" -f [datetime]$Stime
Write-Host $time
This code returns value 12:00
I tried this too -
$fromtime = "11.30"
[datetime]$fromtime12hrFormat = ([datetime]$fromtime)
$fromtime12hrFormat.ToString("hh:mm:ss")
This code returns value 12:00
"11.30" cast to [datetime] with en-US locale will be interpreted as "November 30" at midnight.
Use DateTime.ParseExact() instead:
'{0:HH:mm}' -f [datetime]::ParseExact($Stime, 'HH.mm', $null)

How to generated a timestamp based on another formatted timestamp

I'm attempting to output a timestamp in Powershell to represent the time now (rounded down to the 00 seconds), and another to represent 30 minutes before that. Both timestamps should be formatted yyyy-mm-ddThh:mm:ss.
If I use just Get-Date as when setting $end_time, then $start_time is set too.
$end_time = Get-Date
$start_time = $end_time.AddMinutes(-30)
However, when I format $end_time as required, an error occurs when settings $start_time. It looks like calling -Format returns the date as string rather than a date object.
$end_time = Get-Date -Format s -Second 00
$start_time = $end_time.AddMinutes(-30)
Method invocation failed because [System.String] does not contain a method
named 'addminutes'.
To try and work around this shortcomming I added a $date variable, but now I'm unable to even set $end_time. I guess this is because the formatting is returned by the Get-Date function, and cannot be set retrospectily.
$date = Get-Date
$end_time = $date -Format s -Second 00
Unexpected token '-Format' in expression or statement.
So my question is: if I am unable to manipulate a formatted date, and if I cannot format a pre-generated date as requred, how is it possible to generate two timestamps that are 30 minutes apart (one for 'now', one for 30 minutes ago) and which are formatted as yyyy-mm-ddThh:mm:ss?
Instead of using the -Format parameter of Get-Date, use the .ToString method on the date objects you create instead:
$Date = Get-Date -Second 0
$Date.ToString("yyyy-MM-ddTHH:mm:ss")
$Date.AddMinutes(-30).ToString("yyyy-MM-ddTHH:mm:ss")
Explanation:
Get-Date is executed and returns a DateTime object representing the current date and time with the seconds set to 0. This is then cast to a string using the .ToString method to format per your custom style.
The next command is the same, but before casting it as a formatted string (whereby it loses the date object methods), the .AddMinutes method is used to remove 30 minutes.
Keep $date as datetime, use ToString as required:
$date = Get-date -second 0
$end_time = $date.ToString("yyyy-MM-ddTHH:mm:ss")
$start_time = ($date.AddMinutes(-30)).ToString("yyyy-MM-ddTHH:mm:ss")

Convert day of year value to date in Powershell

In Powershell, converting a date into a day of the year value is easy:
$DayOfYear = (Get-Date).DayofYear
Write-Host $DayOfYear
140
Is there a similar way to convert the day of year back into a date (i.e. 140 = 05/20/2013)?
Try this:
([datetime]"01/01/$((Get-Date).Year)").AddDays(140-1)
20. mai 2013 00:00:00
mai = may in norwegian :-)
You could create a DateTime object representing the start of the year, then add the number of days to it, e.g.:
(New-Object System.DateTime 2013,1,1).AddDays(140-1)
This might be helpful for you:
$startdate_year = ([datetime]"01/01/$((Get-Date).Year)")
$a = (Get-Date $startdate_year).AddDays(139)
"Date: " + $a.ToShortDateString()
Now you will get the result like this:
Date: 5/20/2013
Use this method to avoid [datetime] objects and use Powershell syntax only:
$DayOfYear = (Get-Date).DayOfYear
$Today = (Get-Date -Month 1 -Day 1).AddDays($DayOfYear-1)
"$($Today.ToString("MM/dd/yyyy")) is day $DayOfYear of 365"
Output:
10/03/2017 is day 276 of 365

PowerShell date/time conversion

I have a variable, $date, containing 24 June 2012 00:00:00.
How do I convert this to 24/06/2012?
Use the Get-Date cmdlet together with the Format parameter:
PS> $date = '24 June 2012 00:00:00'
PS> Get-Date $date -Format 'dd/MM/yyyy'
24/06/2012
I tried reading a file with dates formatted day-month-year
The answer above did not work for me, I found a different solution on how to parse my dates and check which one is newer than the current date. This is my adapted code.
$currdateobj = Get-Date
$STARTDATE = "12-05-2017" // specific non-default date format
[DateTime]$startdateobj = [DateTime]::ParseExact($STARTDATE,"dd-MM-yyyy",[System.Globalization.CultureInfo]::InvariantCulture)
if ($startdateobj -lt $currdateobj)
{
// ....
}