How to generated a timestamp based on another formatted timestamp - powershell

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")

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

Powershell - Determine Sunset and Add Time

I have a Powershell script that determines my local sunrise and sunset. However, my end goal is to run a function at 45 minutes past sunset. I know I can't use AddMinutes(45) as that only works with Get-Date. I tried to format the output of the value returned for "sunset", but even formatted to match Get-Date, it still doesn't work. Is there some other method I could use?
$Daylight = (Invoke-RestMethod "https://api.sunrise-sunset.org/json?lat=35.608081&lng=-78.647666&formatted=0").results
$Sunrise = ($Daylight.Sunrise | Get-Date -Format "HH:mm")
$Sunset = ($Daylight.Sunset | Get-Date -Format "dddd, MMMM dd, yyyy hh:mm:ss tt")
If you're using PowerShell Core, the properties Sunrise and Sunset from the object returned by your API query should already be of the type DateTime, however in Windows PowerShell, you would need to cast [datetime] to them to convert them from string. Then .AddMinutes method would work without issues, if you're looking to run a function 45 minutes past Sunset you can try the following assuming this could be a scheduled task:
$Daylight = (Invoke-RestMethod "urlhere").results
$sunset = [datetime] $Daylight.sunset # => [datetime] only needed in Windows PowerShell
if([datetime]::Now -ge $sunset.AddMinutes(45)) {
# run function here
}
Or if you want your script to execute and wait until the right time, you can use a loop:
do {
Start-Sleep -Seconds 60
} until([datetime]::Now -ge $sunset.AddMinutes(45))
# run function here

Subtracting time in 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'

AddDays in powershell

I have a stored procedure which has 2 parameters #from, #to, I want to pass #from the value of $from, which is inputed from powershell GUI. I want #to to be 1 day after #from. I have below code. Which value seems to be passed to #from, but to value is not passed. Any suggestion?
$param1=$sqlcmd.Parameters.Add("#from" , [System.Data.SqlDbType]::DateTime)
$param1.Value=Get-Date $from -format "yyyy-MM-dd HH:mm:ss.fff"
$param2=$sqlcmd.Parameters.Add("#to", [System.Data.SqlDbType]::DateTime)
$param2.Value=Get-Date ($from).AddDate(1) -format "yyyy-MM-dd HH:mm:ss.fff"
If I recall correctly from your previous question, $from is a string, not a date. You can't add days to a string, so you need to convert it to a date first. Also you need .AddDays(1), not .AddDate(1).
$param2.Value = Get-Date (Get-Date $from).AddDays(1) `
-format "yyyy-MM-dd HH:mm:ss.fff"

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)
{
// ....
}