Say a word about different ticks or how not to get an error in Powershell when working with Get-Date

Good day, Powershell lovers.



I love him, and today I noticed one oddity that motivated me to write this post. I think you will be interested too. The case of excess tick. If interested, welcome to cat:



What is the essence of strangeness?



In one processing, for the convenience of selection, the number of days until the end of the month was needed.



This was calculated in one line of this kind:



((Get-date -Day 1).AddMonths(1)-(get-date)).days-1
      
      





What is characteristic is its calculation can give different results:



At first, I thought something was wrong with the code, or with the Powershell version.



I checked it on several cars and realized that the situation is reproducible.



Therefore, I sat down to debut and write a function.



I got this, the comments immediately go to the code:



 Function Get-DaysToEndOfMonths([int]$Month=1) {If($Month -lt 1){[int]$Month = 1} $CurrentDate = get-date #   $CurrentDay = $CurrentDate.day #    $FirstDayCurrentMonths = (Get-date -Day 1) #    #$FirstDayNextMonths = $FirstDayCurrentMonths.AddMonths($Month) #    #,      ,        $LastDay = $FirstDayCurrentMonths.AddMonths($Month).AddDays(-1) #    $DaysToEndOfMonths = $($LastDay - $CurrentDate).Days #     #  New-TimeSpan #$NewTimeSpan = New-TimeSpan -Start $CurrentDate -End $LastDay #$DaysToEndOfMonths = $NewTimeSpan.Days #  Write-debug "$DaysToEndOfMonths days to the end of the next $Month month" } Get-DaysToEndOfMonths(1)
      
      





Well, after I wrote, I sat down to think and came to this line:



 [int]((((Get-Date -day 01).AddMonths(1)).AddDays(-1)).Day-(Get-date).Day)
      
      





She did not give an error, but she could, because:



It turns out that we do not take into account the hour \ minutes \ seconds, or rather the processor clock ticks.

Note that Get-date returns a value in milliseconds.



But if, when performing the calculations, the first and second Get-date calls fell on one tick, then there will be such values:



 (Get-date -day 1).AddMonth(1) = 1.12.2019 15:33:00:500 Get-date = 1.11.2019 15:33:00:500
      
      





Subtract and get 30 00: 00: 00: 000

But if the call to the second Get-date falls on the next tick, then its value will be

=>
 1.11.2019 15:33:00:501
      
      





And then we get the value in
 29 23:59:59:999
      
      





Now that the problem is found, we can do this:



 #     ((((Get-Date -day 01).AddMonths(1)).AddDays(-1))-(Get-date -Hour 0 -Minute 0 -Second 0 -Millisecond 0)).Days
      
      





And we will always have the same value.



Be careful and have a good weekend!



All Articles