reference to datetime in powershell - powershell

$var = "01/01/2020"
$date1 = Get-Date
$date2 = Get-Date
Write-Host $date1.GetType().Name
Write-Host $date2.GetType().Name
$dates = #(
#('date1', [ref]$date1),
#('date2', [ref]$date2)
)
foreach($date in $dates) {
$date[1].Value = Get-Date ([DateTime]::ParseExact($var, 'dd/MM/yyyy', $null)) -Format "dd/MM/yyyy"
}
Write-Host $date1
Write-Host $date2
Write-Host $date1.GetType().Name
Write-Host $date2.GetType().Name
output :
DateTime
DateTime
01/01/2020
01/01/2020
String
String
I do not understand why my dates (date1 and date2) went from DateTime to String ?
How do I fix it ? because the next step in my code is to compare date1 and date2 (I want to compare dates not string obviously)
Help is much appreciate

This is the problem
$date[1].Value = Get-Date ([DateTime]::ParseExact($var, 'dd/MM/yyyy', $null)) -Format "dd/MM/yyyy"
Remove the -Format "dd/MM/yyyy" from your code.
You are parsing a string to a date using [DateTime]::ParseExact then immediately convert it back to a string using -Format "dd/MM/yyyy".
You just need
$date[1].Value = Get-Date ([DateTime]::ParseExact($var, 'dd/MM/yyyy', $null))

Related

How to do time "HH:mm" comparison in Powershell?

Apparently my code is like this and it is now working. I think the logic is already there. the $openTime and $closeTime is read from csv using import-csv in "HH:mm" form.
$openTime = $ip.openTime
$closeTime = $ip.closeTime
$time = Get-Date -UFormat "%R"
if (($time -ge $openTime) -and ($time -le $closeTime)) {
Write-Host "Store is Open!" -ForegroundColor Green
}else{
Write-Host "Store is outside open hours!" -ForegroundColor Red
}
powershell 7
$csv = #"
store, openTime, closeTime
Wallmart, 08:00, 18:00
Ikea, 10:00, 20:30
"# | ConvertFrom-Csv
Get-Date
$csv | ForEach-Object{
[int]([datetime]::Now - [datetime]::Today).TotalMinutes -in (.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.openTime.split(":"))..(.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.closeTime.split(":")) ? "Store {0} is Open! " -f $_.store : "Store {0} is outside open hours!" -f $_.store
}
16 февраля 2021 г. 8:52:42
Store Wallmart is Open!
Store Ikea is outside open hours!
powershell 5
$csv = #"
store, openTime, closeTime
Wallmart, 08:00, 18:00
Ikea, 10:00, 20:30
"# | ConvertFrom-Csv
Get-Date
$csv | ForEach-Object{
("Store {0} is outside open hours!", "Store {0} is Open! ")[[int]([datetime]::Now - [datetime]::Today).TotalMinutes -in (.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.openTime.split(":"))..(.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.closeTime.split(":"))] -f $_.store
}
Try it online!
I find it's much easier to work with date and times if I convert them to [DateTime] objects. We can use the DateTime class method ParseExact to convert the time into [DateTime] objects for us. This object will actually contain today's date as well as the time we supply, but for our purposes this is fine since the $time object also will be today's date. For the current time ($time) just let Get-Date return to us a [DateTime] object that will represent the current date and time (now). After that the rest of your code works as expected. Hurray!
# this $ip hashtable object just represents data similar to your csv import
$ip = #{
openTime = "09:00"
closeTime = "21:00"
}
$openTime = [datetime]::ParseExact($ip.openTime, 'HH:mm', $null)
$closeTime = [datetime]::ParseExact($ip.closeTime, 'HH:mm', $null)
$time = Get-Date
if (($time -ge $openTime) -and ($time -le $closeTime)) {
Write-Host "Store is Open!" -ForegroundColor Green
}
else {
Write-Host "Store is outside open hours!" -ForegroundColor Red
}
If you are working with the time are imported from csv, make sure the time format in the csv file is in "HH:mm"

Compare date from string with current date

I am have string which contain date and I want to compare that all last 15 days date with the date in string.
I have stored all 15 days date in array and comparing with the date in string.
#last 15 days date.
$Q = #()
$Q = for ($i=15; $i -gt 1; $i--) {
$date=Get-Date -DisplayHint Date #-Format "dd MMM yyyy"
$final=$date.AddDays(-$i)
$final.tostring("dd MMM yyyy")
}
# $array.'Description' have string like this "Enabled AD ID as per Call id: 509112 29 Oct 2019"
#comparing
if($array.'Description' -notcontains $Q){
Write-host ("true")
}else
{
write-host ("false")
}
I want comparing result.
You can split $array.'Description', then join the last three elements and then compare it with $Q.
($($array.'Description').Split(" ") | Select-Object -Last 3) -join " "
The comparison would look something like:
if ((($($array.'Description').Split(" ") | Select-Object -Last 3) -join " ") -notcontains $Q){
Write-host ("true")
}else
{
write-host ("false")
}
I think you should always compare dates to dates, not their string representation unless it is in Sortable format.
Below code takes the date string from the Description attribute and converts it to a local DateTime object to compare against:
$refDate = (Get-Date).AddDays(-15).Date # midnight 15 days ago
$array | ForEach-Object {
# parse a date object from the Description string
$dateString = ([regex]'(\d{1,2} \w{3} \d{4})$').Match($_.Description).Groups[1].Value
$date = [datetime]::ParseExact($dateString, 'd MMM yyyy', [cultureinfo]"en-US")
# make it a Local date
$date = [datetime]::SpecifyKind($date, 'Local')
if ($date -gt $refDate) {
# the description date is inside the last 15 days
Write-Host "True"
}
else { Write-Host "False" }
}
Edit
As per Esperanto57's comment, in case the Description string does not contain a date to parse, below uses a try{..} catch{..} block to tackle that:
$array | ForEach-Object {
try {
# parse a date object from the Description string
$dateString = ([regex]'(\d{1,2} \w{3} \d{4})$').Match($_.Description).Groups[1].Value
$date = [datetime]::ParseExact($dateString, 'd MMM yyyy', [cultureinfo]"en-US")
# make it a Local date
$date = [datetime]::SpecifyKind($date, 'Local')
if ($date -gt $refDate) {
# the description date is inside the last 15 days
Write-Host "True"
}
else { Write-Host "False" }
}
catch {
Write-Host "False. (The Description attribute does not contain a date.)"
}
}

Converting a string to date-time format

I am importing a csv to an excel using powershell. Both of my columns have date-time in the following format:
2019-01-25T19:58:28.000Z
I want to convert the column to the following format "dd/MM/yyyy h:mm"
I tried the following two things and none of them worked:
[datetime]::ParseExact($fullinfo.A, "dd/MM/yyyy h:mm", $null)
$excel.Columns.item('b').NumberFormat = "dd/MM/yyyy h:mm"
$fullInfoSheet = $workbook.Worksheets.Item(1)
$fullInfoSheet.cells.item(1,1) = "Column A"
$fullInfoSheet.cells.item(1,2) = "Column B"
$fullinfolist = Import-Csv -Path $csvfullFile -Header A, B
$i = 2
foreach($fullinfo in $fullinfolist)
{
$fullInfoSheet.cells.item($i,1) = [datetime]::ParseExact($fullinfo.A, "dd/MM/yyyy h:mm", $null)
$fullInfoSheet.cells.item($i,2) = $fullinfo.B
$i++
}
$excel.Columns.item('b').NumberFormat = "dd/MM/yyyy h:mm"
This produces output in your desired format
$InputDate = '2019-01-25T19:58:28.000Z'
get-date $InputDate -Format 'dd/MM/yyyy h:mm'

Date time parsing to another format

I need to get the end date of the month we are in.
I tried with this code:
$CURRENTDATE=GET-DATE -Format "dd/MM/yyyy"
$FIRSTDAYOFMONTH=GET-DATE $CURRENTDATE -Day 1
$LASTDAYOFMONTH=GET-DATE $FIRSTDAYOFMONTH.AddMonths(1).AddSeconds(-1)
echo $LASTDAYOFMONTH
This gives me the date of the end of the month. But i need it in another format (dd/MM/yyyy).
But can't seem to get my head around it. A push in the right direction would be great.
Adapting Mike F. Robbins code
$currentDate = Get-Date
$lastDay = [DateTime]::DaysInMonth($currentDate.Year, $currentDate.Month)
$lastDayOfMonth = Get-Date ([DateTime]"$($currentDate.Month), $LastDay, $($currentDate.Year)") -Format 'dd/MM/yyyy'
Write-Host $lastDayOfMonth
Or if you want to use your existing code:
$CurrentDate = Get-Date -Format "dd/MM/yyyy"
$FirstDayOfMonth = Get-Date $CurrentDate -Day 1
$LastDayOfMonth = Get-Date $FirstDayOfMonth.AddMonths(1).AddSeconds(-1) -Format "dd/MM/yyyy"
Write-Output $LastDayOfMonth

Check if date in past

$olddate = Get-Date -Date "31-dec-2013 00:00:00" -Format d.M.yyyy
$Now = Get-date -Format d.M.yyyy
How can I check if $olddate is earlier than $Now?
If your store them as DateTime instead of as formatted strings, you can use the less-than operator (-lt) just like with regular numbers, and then use the format operator (-f) when you need to actually display the date:
$olddate = Get-Date -Date "31-dec-2013 00:00:00"
$Now = Get-Date
if($olddate -lt $Now){
"`$olddate is in the past!"
"{0:d.M.yyyy}" -f $olddate
"{0:d.M.yyyy}" -f $Now
}
You can also do a comparison on Ticks. I.e.: $olddate.Ticks will be -lt then $Now.Ticks.