【问题标题】:Why does ParseExact in my PowerShell script accept an int64 and not a string?为什么我的 PowerShell 脚本中的 ParseExact 接受 int64 而不是字符串?
【发布时间】:2017-10-25 23:31:11
【问题描述】:

虽然我能够实现我的目标,但我不明白为什么,我担心我仍然做错了什么。

上下文是检索一个日期时间值,以便与另一个日期进行比较,使用 FTP 检索文件的时间戳。日期时间以字符串形式接收:

$FTPrequest = [System.Net.FtpWebRequest]::Create($FTPTargetFile)
$FTPrequest.Method = [System.Net.WebRequestMethods+FTP]::GetDateTimestamp
$FTPrequest.Credentials = $Credentials
$response = $FTPrequest.GetResponse().StatusDescription
$tokens = $response.Split(" ")
if ($tokens[0] -eq 213) {
    $Timestampdata = $tokens[1]
} else {
    Write-Output "FTP timestamp request for " + $FTPTargetFile + " returned an error"
}

我发现的几乎所有可用资源都清楚地表明 ParseExact 使用字符串来派生日期时间,如下面的脚本行所示:

$d = [DateTime]::ParseExact($Timestampdata,"yyyyMMddHHmmss",$null)

但无论是在脚本中还是在命令提示符下,上述行始终返回以下错误:

使用“3”参数调用“ParseExact”的异常:“无法识别字符串 作为有效的日期时间。” 在 C:\hw-sw\powershell\FTPupload 选项 - getFileInfo.ps1:38 char:1 + $d = [日期时间]::ParseExact($Timestampdata,"yyyyMMddHHmmss",$null) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : 格式异常

我发现了 2 个链接(lin1link2 - 第二个链接解决了一个稍微不同的问题,但重点仍然存在)建议 ParseExact() 使用 intXX 代替,如以下脚本行所示:

$d = [DateTime]::ParseExact([convert]::ToInt64($Timestampdata),"yyyyMMddHHmmss",$null)

是的,上面的行运行没有错误。

虽然我很高兴为我的脚本问题找到了一个潜在的解决方案,但我很不安,因为我不明白为什么 ParseExact 使用的是 int64,而不是我预期的字符串。

PowerShell 中是否有一些设置会改变它的工作方式?我相信我一定是犯了一些简单的错误,但我想不通。

【问题讨论】:

  • 字符串中有空格吗?试试$d = [datetime]::parseexact($Timestampdata.Trim(),"yyyyMMddHHmmss",$null)
  • 好主意。但是,是的,我确实尝试过 .Trim()。行为没有变化。
  • 无法复制。请提供示例输入。

标签: powershell


【解决方案1】:
static datetime ParseExact(string s, string format, System.IFormatProvider provider)
static datetime ParseExact(string s, string format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style)
static datetime ParseExact(string s, string[] formats, System.IFormatProvider provider, System.Globalization.DateTimeStyles style)

这些是 PSv5.1 上 ParseExact 的重载方法。您正在向它传递一个 $null 提供程序。

Additional information

Your use case

阅读更多内容后,请确保您的第一个参数没有空格,否则它将失败。还要确保您当前的文化对于您期望的行为是正确的。

【讨论】:

  • [System.DateTime]::ParseExact('20171025110130',"yyyyMMddHHmmss",$null) 为我工作。 [System.DateTime]::ParseExact('20171025110130',"yyyyMMddHHmmss",[System.Globalization.CultureInfo]::InvariantCulture.DateTimeFormat) 可能更正确,但 $null 在这种格式下工作得很好。
  • @BaconBits The DateTime.ParseExact(String, String, IFormatProvider) method parses the string representation of a date, which must be in the format defined by the format parameter. It also requires that the <Date> and <Time> elements of the string representation of a date and time appear in the order specified by format, and that s have no white space other than that permitted by format. 虽然,我看到了这个注释:If provider is null, the CultureInfo object that corresponds to the current culture is used. 不太喜欢默认行为
  • @BaconBits。我得到了同样的结果,这令人抓狂。当我指定一个文字字符串时,它可以工作!一旦我替换了我的变量名,在这种情况下为 $Timestampdata(即使使用上面提到的 Trim()),它也不起作用。
  • @Alan 你不能在$Timestampdata 中有任何空格。 .Trim() 只删除末尾的空格。试试这个:$Timestampdata = $Timestampdata -replace '\s'
  • @TheIncorrigible1。我相信我理解你的观点,但我可能遗漏了一些基本的东西。我确保没有空白。我还确保字符串变量的格式适合我的格式化模板。这是一个漫长的教训,因为 FTP 返回一个 24 小时格式,我不得不学习格式化字符串中 hhHH 之间的区别;但我确信现在是正确的。您发布的链接中的重载仍然将传入的参数定义为字符串,但我的经验结果似乎需要 intXX,因此我很困惑。
猜你喜欢
  • 2013-07-24
  • 2013-12-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 2016-07-11
相关资源
最近更新 更多