#powershell #datetime #timespan
#powershell #datetime #промежуток времени
Вопрос:
Я пытался получить количество дней между двумя датами, но получаю следующую ошибку
Любые предложения будут с благодарностью
$Days = $expiration - $currentDate
Cannot convert value "12/28/2020" to type "System.Int32". Error: "Input string was not in a correct format."
At line:1 char:1
$Days = $expiration - $currentDate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [], RuntimeException
FullyQualifiedErrorId : InvalidCastFromStringToInteger
ниже приведен фрагмент кода для справки
$expiration = $QueryResults.Results.ExpiryDate_s
$expiration
12/28/2020
$currentDate = Get-Date -Format 'MM/dd/yyyy'
$currentDate
09/30/2020
$expiration.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
$currentDate.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
Комментарии:
1. Вы уверены, что хотите преобразовать их в целые числа, а не в DateTime?
Ответ №1:
PowerShell напрямую поддерживает вычитание экземпляров [datetime]
( System.DateTime
), результат которого отображается как промежуток времени, выраженный как экземпляр [timespan]
( System.TimeSpan
) .
Чтобы это сработало, оба операнда, передаваемые оператору -
(вычитания), должны иметь тип [datetime]
, который в вашем случае можно просто получить, приведя [1] ваши строковые операнды к этому типу (вместо вызова Get-Date -Format 'MM/dd/yyyy'
вы должны просто вызвать (Get-Date).Date
, чтобы вернуть [datetime]
экземпляр напрямую):
PS> [datetime] '12/28/2020' - [datetime] '09/30/2020'
Days : 89
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 0
Ticks : 76896000000000
TotalDays : 89
TotalHours : 2136
TotalMinutes : 128160
TotalSeconds : 7689600
TotalMilliseconds : 7689600000
Чтобы получить только количество дней между двумя датами, используя текущую дату (без компонента времени суток) в качестве RHS:
$days = ([datetime] '12/28/2020' - (Get-Date).Date).Days
Что касается того, что вы пробовали:
Если вы передаете оператору LHS со строковым типом -
, PowerShell пытается интерпретировать его как число.
Поскольку строка, такая как '12/28/2020'
, не может быть проанализирована как числовой тип, операция завершается с ошибкой. Чтобы предоставить более очевидный пример:
PS> 'I am not a number' - 1
Cannot convert value "I am not a number" to type "System.Int32"
...
[int]
( System.Int32
) просто является единственным числовым типом, выбранным для сообщения об ошибке.
[1] Обратите внимание, что приведения PowerShell всегда основаны на инвариантной культуре, которая основана на культуре английского языка США, независимо от того, какая культура действует в настоящее время. Это означает, что [datetime]
приведение принимает любую строку [datetime]::Parse($string, $null)
, которая принимает, включая строки даты за первый месяц '1/13/2020'
, такие как, а также менее неоднозначные форматы, такие как '2020-1-13'
Ответ №2:
Вы пытаетесь выполнить математические вычисления для значений типа данных datetime, что неверно.
Я полагаю, что вы могли бы использовать New-TimeSpan
командлет для удовлетворения ваших потребностей. Вот так:
PS C:WINDOWSsystem32> New-TimeSpan -Start '01.01.2020' -End $(Get-Date)
Days : 274
Hours : 3
Minutes : 38
Seconds : 17
Milliseconds : 295
Ticks : 236866972950824
TotalDays : 274,151589063454
TotalHours : 6579,63813752289
TotalMinutes : 394778,288251373
TotalSeconds : 23686697,2950824
TotalMilliseconds : 23686697295,0824
Вы также можете вызвать методы переменной типа данных datetime, такие как AddDays()
. Вот так:
PS C:WINDOWSsystem32> $CurrentDate = Get-Date
PS C:WINDOWSsystem32> $CurrentDate.AddDays(-274)
1 января 2020 г. 3:40:59
Комментарии:
1. Спасибо за ваш быстрый ответ. Теперь все ясно, и скрипт работает нормально с
New-TimeSpan -Start -End
2. Хотя ваше решение работает, ваше утверждение о том, что попытка выполнить «неверную математику для значений типа данных datetime» является ложной: использование функции вычитания (
-
) между двумя[datetime]
экземплярами работает просто отлично и напрямую возвращает[timespan]
экземпляр. единственной проблемой @VINODKUMAR было использование строковых операндов как есть, без приведения к[datetime]
первому.