Как преобразовать строковое значение в тип «System.Int32» в PowerShell

#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] первому.