【问题标题】:Powershell - compare date with CSV datePowershell - 将日期与 CSV 日期进行比较
【发布时间】:2020-02-06 11:21:49
【问题描述】:

我正在尝试将输入的日期与 CSV 中的日期进行比较,如果输入的日期早于 CSV 中的日期,则会显示一条消息。

我遇到了困难,不确定是否需要将 CSV 中的日期从字符串转换为正确比较。

代码到此为止:

$CSV=Import-Csv C:\Users\person\Desktop\date.csv 
$InputDate = Get-Date -Format "MM/dd/yyyy" (Read-Host -Prompt 'Enter the date')
$CreatedDate = Get-Date -Format "MM/dd/yyyy HH:mm" $CSV.updated

if($InputDate -gt $CreatedDate) {
  write-host "Input Newer"
}
else {
  write-host "Input Older"
}

比较似乎无法正常工作。

CSV 格式如下(包含一行,因此可以假设$CSV.updated 包含一个单个 日期字符串):

updated
11/07/2016 16:14

【问题讨论】:

    标签: powershell datetime datetime-format


    【解决方案1】:

    Kiran Patnayakuni's answer 提供了有效的解决方案;让我更清楚地说明问题所在:

    • 您似乎期望-Format "MM/dd/yyyy" 指定一种输入解析 格式;事实上,它会格式化输出,然后变成[string]

      • 不过,要进行有意义的日期比较,您需要一个 [datetime] 实例。
    • 您对(隐含的)-Date 参数((Read-Host ...)$csv.updated)的参数已隐含根据当前文化识别的标准格式进行了解析> (System.Globalization.CultureInfo.CurrentCulture)。

    因此:

    • 如果您的参数已经被 implicit 解析正确识别(正如您接受 Kiran 的回答所暗示的那样),解决方案是简单地 删除 -Format 参数你的代码:

        # Parse each input string implicitly, based on the current culture,
        # and output a [datetime] instance, which will compare as expected
        # with `-gt`
        $InputDate = Get-Date (Read-Host -Prompt 'Enter the date')
        $CreatedDate = Get-Date $CSV.updated
      
    • 相比之下,如果您确实需要通过"MM/dd/yyyy" 格式字符串显式解析以便识别您的参数,请调用.NET 方法[datetime]::ParseExact(<string>, <format>[, <culture>]) (System.DateTime.ParseExact);例如:

        # Note: The input string must match the format *exactly*
        $InputDate = [datetime]::ParseExact(
          (Read-Host -Prompt 'Enter the date'), # input string
          "MM/dd/yyyy", # format string
          $null  # default to the current culture's rules
        ) 
      

    继续阅读背景信息。


    Get-Date输入输出格式化数据类型:

    -Format "MM/dd/yyyy" 没有指定 input 解析格式,它指定了 output 字符串格式化格式,这有两个含义:

    • String 传递给输入参数 -Date(第一个 positional 参数绑定到)的输入被隐式解析 为 [datetime],基于 当前文化[1] 识别的标准字符串格式;实际上,在幕后调用了以下代码:

        [datetime]::Parse((Read-Host -Prompt 'Enter the date'), [cultureinfo]::CurrentCulture)
      
      • (在上面的调用中省略[cultureinfo]::CurrentCulture具有相同的效果。)
      • 警告当您字符串转换为[datetime]时,它是invariant文化(@ 987654353@,基于美国英语)应用,PowerShell经常这样做,以保证跨文化代码的稳定性; Get-Date 之类的 cmdlet 是不是文化不变的,这是一个历史事故,由于害怕破坏旧代码而无法纠正;背景见this GitHub issue。例如,在文化fr-FR(法语)生效的情况下,[datetime] '12/1] 产生 12 月 1 日(第一个月),而Get-Date -Date '12/1' 产生 1 月 12 日(第一天) .
    • Get-Date 命令将返回一个(格式化的)字符串,而不是[datetime] 实例;也就是说,在输入上隐式解析的[datetime] 实例基于传递给-Format 的格式字符串进行格式化,基于current 文化的规则;如果$dt 包含[datetime] 实例,则-Format "MM/dd/yyyy" 等效于(请注意直接调用System.DateTime.ToString() 可以让您选择指定一个不同的文化,-Format 没有):

        $dt.ToString("MM/dd/yyyy", [cultureinfo]::CurrentCulture)
      

    (从 PowerShell v7.0 开始),Get-Date cmdlet 支持为 input 解析指定格式字符串。

    • 如上所述,将字符串传递给 -Date 会导致它被隐式解析,基于当前文化识别的标准日期/时间格式 .

    • 您必须直接调用 .NET 方法 [datetime]::ParseExact(<string>, <format>[, <culture>]) (System.DateTime.ParseExact),如顶部所示。

    • 一旦你有了一个[datetime] 实例,你就可以将它(通过-Date)传递给Get-Date -Format 以获得当前文化的格式化字符串表示;或者,您可以直接在实例上调用.ToString(<format>[, <culture>]) (System.DateTime.ToString),这也使您可以选择为不同的文化设置格式。

    至于Get-Date输入输出数据类型

    从根本上说,输入 的传递方式(特定参数)决定了结果[datetime] 实例的解释方式,具体取决于 cmdlet 如何选择实例的 .Kind 属性值(UtcLocalUnspecified)。

    .Kind 属性值确定[datetime] 实例代表的特定全局时间点(如果有)。 .Kind 值也会影响实例的字符串表示,具体取决于应用的特定格式(特别是包含时区信息)。

    生成的[datetime] 实例是:

    • 或者:直接输出(默认)
    • 或:如果传递了-Format 参数,则作为派生请求的字符串表示形式 ([string]) 的基础。

    Get-Date 确定.Kind 属性值如下:

    • 使用 no -Date 参数,您将获得一个 Local 实例(代表当前时间点)

      • (除非一个字符串传递给-Date),使用各种偏移参数,例如-Year-Day,也会产生一个Local实例。李>
    • 如果-Date 参数已经 类型为[datetime],则该实例按原样使用,这意味着现有的.Kind 属性值被保留。

    • 使用 string -Date 参数(被隐式解析),.Kind 值将是 Unspecified(表示一个 抽象 时间点,没有引用特定时区),包括是否与-Year 等参数结合使用。

    • 数字-Date 参数(例如637165787436900010)被解释为System.DateTime.Ticks 值,这也会产生Unspecified 实例。

    注意:PowerShell [Core] 7.1 将引入一个-AsUTC 开关,使输出/待字符串格式的实例类似于Utc-AsLocal-AsUnspecified 开关(和/或 -AsKind <kind> 参数)也在讨论中 - 请参阅 this GitHub issue


    [1] 如果输入已经是[datetime] 实例,则按原样使用。

    【讨论】:

      【解决方案2】:

      您需要将字符串中的日期解析为 datetime 类型来进行日期比较。

      $CSV = Import-Csv C:\Users\person\Desktop\date.csv 
      $InputDate = [datetime]::Parse( $(Read-Host -Prompt 'Enter the date (MM/dd/yyyy)') )
      $CreatedDate = [datetime]::Parse( $CSV.updated )
      if($InputDate -gt $CreatedDate)
      {write-host "Input Newer"}
      else
      {write-host "Input Older"}
      

      【讨论】:

        猜你喜欢
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-03
        • 1970-01-01
        • 1970-01-01
        • 2012-09-26
        • 2017-10-01
        相关资源
        最近更新 更多