Powershell - 将日期与 CSV 日期进行比较
Powershell - compare date with CSV date
我正在尝试将输入的日期与 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
您需要将字符串中的日期解析为日期时间类型以进行日期比较。
$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"}
提供了一个有效的解决方案;让我更清楚地说明问题是什么:
您似乎希望-Format "MM/dd/yyyy"
指定输入解析格式;事实上,它格式化 output,然后变成 [string]
.
- 但是,为了进行有意义的日期比较,您需要一个
[datetime]
实例。
您对(隐含的)-Date
参数((Read-Host ...)
、$csv.updated
)的参数被隐含 解析,基于当前文化 (System.Globalization.CultureInfo.CurrentCulture
) 认可的标准格式。
因此:
如果 隐式 解析已经正确识别了您的论点(正如您接受 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 字符串-格式化 format,这有两个含义:
String 输入传递给输入参数 -Date
(第一个 positional 参数绑定到) 被隐式 解析 为[datetime]
,基于 标准 当前文化[1]识别的字符串格式;实际上,在幕后调用了以下内容:
[datetime]::Parse((Read-Host -Prompt 'Enter the date'), [cultureinfo]::CurrentCulture)
- (在上面的调用中省略
[cultureinfo]::CurrentCulture
具有相同的效果。)
- 警告:当你转换一个字符串到
[datetime]
时,它是 不变 文化([cultureinfo]::InvariantCulture
,基于美式英语),PowerShell 经常这样做是为了代码的稳定性文化;诸如 Get-Date
之类的 cmdlet 是 not 文化不变的是一个历史事故,由于担心破坏旧代码而不会得到纠正;背景见 this GitHub issue。例如,文化 fr-FR
(法语)生效,[datetime] '12/1]
产生 12 月 1 日 (第一个月),而 Get-Date -Date '12/1'
产生 1月12日(第一天)。
Get-Date
命令将return一个(格式化的)字符串而不是[datetime]
实例;也就是说,根据 current 文化的规则,根据传递给 -Format
的格式字符串对输入隐式解析的 [datetime]
实例进行格式化;如果 $dt
包含一个 [datetime]
实例,-Format "MM/dd/yyyy"
等同于 (请注意直接调用 System.DateTime.ToString()
如何为您提供选项指定 不同的 文化,而 -Format
没有):
$dt.ToString("MM/dd/yyyy", [cultureinfo]::CurrentCulture)
(从 PowerShell v7.0 开始),Get-Date
cmdlet 不 支持为 指定格式字符串输入解析.
如上所述,根据 标准 date/time 格式 被当前文化 识别。
您必须直接调用 .NET 方法 [datetime]::ParseExact(<string>, <format>[, <culture>])
(System.DateTime.ParseExact
),如上一节所示。
一旦你有一个 [datetime]
实例,你可以将它(通过 -Date
)传递给 Get-Date -Format
以获得 [=155] 的格式化字符串表示=]当前文化;或者,您可以直接在实例上调用 .ToString(<format>[, <culture>])
(System.DateTime.ToString
),这样您还可以选择针对 不同文化 .
进行格式化
至于Get-Date
输入输出数据类型:
从根本上说,输入 的传递方式(特定参数)决定了结果 [datetime]
实例的解释方式,具体取决于 cmdlet 的方式选择实例的
.Kind
属性 值(Utc
、Local
或 Unspecified
)。
.Kind
属性 值决定了 [datetime]
实例代表的特定全局时间点(如果有)。 .Kind
值也会影响实例的字符串表示,具体取决于应用的特定格式(特别是包含时区信息)。
生成的 [datetime]
实例是:
- 或者:输出直接(默认)
- 或:如果传递了
-Format
参数,是派生请求的 字符串表示的基础 ([string]
).
Get-Date
确定 .Kind
属性 值如下:
用没有 -Date
参数,你得到一个Local
实例(代表当前时间点)
- (除非字符串被也传递给
-Date
),使用各种偏移参数,例如-Year
和-Day
,也会生成一个 Local
实例。
对于 -Date
已经 是 类型 [datetime]
的参数,该实例按原样使用,这意味着保留现有 .Kind
属性 值。
使用 string -Date
参数(隐式解析),.Kind
值将是 Unspecified
(表示一个抽象的时间点,不参考具体时区),包括如果结合-Year
.
等参数
A numeric -Date
参数(例如,637165787436900010
)被解释为 System.DateTime.Ticks
值,这也生成一个 Unspecified
实例。
注意:PowerShell [Core] 7.1 将引入一个 -AsUTC
开关,使输出/待格式化的实例成为 Utc
类型; -AsLocal
和 -AsUnspecified
开关(and/or 和 -AsKind <kind>
参数)也在讨论中 - 请参阅 this GitHub issue。
[1] 如果输入已经是 [datetime]
实例,则按原样使用。
我正在尝试将输入的日期与 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
您需要将字符串中的日期解析为日期时间类型以进行日期比较。
$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"}
您似乎希望
-Format "MM/dd/yyyy"
指定输入解析格式;事实上,它格式化 output,然后变成[string]
.- 但是,为了进行有意义的日期比较,您需要一个
[datetime]
实例。
- 但是,为了进行有意义的日期比较,您需要一个
您对(隐含的)
-Date
参数((Read-Host ...)
、$csv.updated
)的参数被隐含 解析,基于当前文化 (System.Globalization.CultureInfo.CurrentCulture
) 认可的标准格式。
因此:
如果 隐式 解析已经正确识别了您的论点(正如您接受 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 字符串-格式化 format,这有两个含义:
String 输入传递给输入参数
-Date
(第一个 positional 参数绑定到) 被隐式 解析 为[datetime]
,基于 标准 当前文化[1]识别的字符串格式;实际上,在幕后调用了以下内容:[datetime]::Parse((Read-Host -Prompt 'Enter the date'), [cultureinfo]::CurrentCulture)
- (在上面的调用中省略
[cultureinfo]::CurrentCulture
具有相同的效果。) - 警告:当你转换一个字符串到
[datetime]
时,它是 不变 文化([cultureinfo]::InvariantCulture
,基于美式英语),PowerShell 经常这样做是为了代码的稳定性文化;诸如Get-Date
之类的 cmdlet 是 not 文化不变的是一个历史事故,由于担心破坏旧代码而不会得到纠正;背景见 this GitHub issue。例如,文化fr-FR
(法语)生效,[datetime] '12/1]
产生 12 月 1 日 (第一个月),而Get-Date -Date '12/1'
产生 1月12日(第一天)。
- (在上面的调用中省略
Get-Date
命令将return一个(格式化的)字符串而不是[datetime]
实例;也就是说,根据 current 文化的规则,根据传递给-Format
的格式字符串对输入隐式解析的[datetime]
实例进行格式化;如果$dt
包含一个[datetime]
实例,-Format "MM/dd/yyyy"
等同于 (请注意直接调用System.DateTime.ToString()
如何为您提供选项指定 不同的 文化,而-Format
没有):$dt.ToString("MM/dd/yyyy", [cultureinfo]::CurrentCulture)
(从 PowerShell v7.0 开始),Get-Date
cmdlet 不 支持为 指定格式字符串输入解析.
如上所述,根据 标准 date/time 格式 被当前文化 识别。
您必须直接调用 .NET 方法
[datetime]::ParseExact(<string>, <format>[, <culture>])
(System.DateTime.ParseExact
),如上一节所示。一旦你有一个
进行格式化[datetime]
实例,你可以将它(通过-Date
)传递给Get-Date -Format
以获得 [=155] 的格式化字符串表示=]当前文化;或者,您可以直接在实例上调用.ToString(<format>[, <culture>])
(System.DateTime.ToString
),这样您还可以选择针对 不同文化 .
至于Get-Date
输入输出数据类型:
从根本上说,输入 的传递方式(特定参数)决定了结果 [datetime]
实例的解释方式,具体取决于 cmdlet 的方式选择实例的
.Kind
属性 值(Utc
、Local
或 Unspecified
)。
.Kind
属性 值决定了 [datetime]
实例代表的特定全局时间点(如果有)。 .Kind
值也会影响实例的字符串表示,具体取决于应用的特定格式(特别是包含时区信息)。
生成的 [datetime]
实例是:
- 或者:输出直接(默认)
- 或:如果传递了
-Format
参数,是派生请求的 字符串表示的基础 ([string]
).
Get-Date
确定 .Kind
属性 值如下:
用没有
-Date
参数,你得到一个Local
实例(代表当前时间点)- (除非字符串被也传递给
-Date
),使用各种偏移参数,例如-Year
和-Day
,也会生成一个Local
实例。
- (除非字符串被也传递给
对于
-Date
已经 是 类型[datetime]
的参数,该实例按原样使用,这意味着保留现有.Kind
属性 值。使用 string
等参数-Date
参数(隐式解析),.Kind
值将是Unspecified
(表示一个抽象的时间点,不参考具体时区),包括如果结合-Year
.A numeric
-Date
参数(例如,637165787436900010
)被解释为System.DateTime.Ticks
值,这也生成一个Unspecified
实例。
注意:PowerShell [Core] 7.1 将引入一个 -AsUTC
开关,使输出/待格式化的实例成为 Utc
类型; -AsLocal
和 -AsUnspecified
开关(and/or 和 -AsKind <kind>
参数)也在讨论中 - 请参阅 this GitHub issue。
[1] 如果输入已经是 [datetime]
实例,则按原样使用。