Diga uma palavra sobre diferentes ticks ou como não obter um erro no Powershell ao trabalhar com Get-Date

Bom dia, amantes do PowerShell.

Eu o amo, e hoje notei uma estranheza que me motivou a escrever este post. Eu acho que você também estará interessado. O caso de excesso de carrapato. Se estiver interessado, bem-vindo ao gato:

Qual é a essência da estranheza?

Em um processamento, para conveniência da seleção, era necessário o número de dias até o final do mês.

Isso foi calculado em uma linha desse tipo:

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

O que é característico é que seu cálculo pode fornecer resultados diferentes:

No começo, pensei que havia algo errado com o código ou com a versão do Powershell.

Eu verifiquei em vários carros e percebi que a situação é reproduzível.

Portanto, sentei-me para estrear e escrever uma função.

Eu entendi, os comentários vão imediatamente para o código:

 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) 

Bem, depois que escrevi, sentei-me para pensar e cheguei a esta linha:

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

Ela não deu um erro, mas talvez porque:

Acontece que não levamos em consideração a hora \ minuto \ segundo, ou melhor, o relógio do processador bate.
Observe que Get-date retorna um valor em milissegundos.

Mas se, ao executar os cálculos, a primeira e a segunda chamada Get-date caírem em um único tique, haverá esses valores:

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

Subtraia e obtenha 30 00: 00: 00: 000
Mas se a chamada para o segundo Get-date cair no próximo tick, seu valor será
=>
 1.11.2019 15:33:00:501 

E então obtemos o valor em
 29 23:59:59:999 

Agora que o problema foi encontrado, podemos fazer o seguinte:

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

E sempre teremos o mesmo significado.

Tenha cuidado e tenha um bom fim de semana!

Source: https://habr.com/ru/post/pt474204/


All Articles