【问题标题】:Trying to convert string to datetime using ParseExact尝试使用 ParseExact 将字符串转换为日期时间
【发布时间】:2019-06-02 22:19:43
【问题描述】:

我正在尝试将类似 '5/29/2019 8:46:47 PM' 的字符串转换为 datetime 以用作 PowerShell 对象,但出现错误

我正在尝试使用[datetime]::ParseExact 方法

$Date = "5/29/2019 8:46:47 PM"

[datetime]::ParseExact($Date,'MM dd yyyy HH:mm:ss', $null)

我没有得到一个日期时间对象,而是得到了这个错误:

使用“3”个参数调用“ParseExact”的异常:“字符串未被识别为有效的日期时间。”

任何帮助将不胜感激。

【问题讨论】:

  • 您需要包含 AM/PM 代码 [tt] 并从 HH 24 小时格式切换到 hh 12 小时格式并使用相同的分隔符。

标签: powershell datetime


【解决方案1】:

postanote's answer 包含有效的解决方案,但值得分析问题。

首先,只需将您的字符串转换为[datetime] 就足够了,因为您的输入字符串是根据invariant文化的规则直接识别的 strong> PowerShell 在这种情况下适用,而与 当前 文化无关(不变文化意味着文化中立,并且基于美国英语文化):

PS> [datetime] "5/29/2019 8:46:47 PM"

Wednesday, May 29, 2019 8:46:47 PM

在幕后,PowerShell 将其转换为以下调用:

[datetime]::Parse("5/29/2019 8:46:47 PM", [cultureinfo]::InvariantCulture)

相比之下,Get-Date 当前文化很敏感:

# Works, but only in cultures that use AM / PM and place the month *first* in
# dates, notably, US-English.
PS> Get-Date -Date "5/29/2019 8:46:47 PM"

Wednesday, May 29, 2019 8:46:47 PM

上述方法在诸如fr-FR(法语(法国))这样的文化中会失败,在这种文化中,是第一位的。

这个类型转换和 cmdlet 参数之间数据类型转换行为的不幸差异是一个长期存在的错误,记录在 in this GitHub issue;但是,出于向后兼容的原因,它不会被修复。


至于你尝试了什么

正如Lee_Daily 指出的那样,您的问题是您的格式字符串'MM dd yyyy HH:mm:ss' 与输入日期字符串"5/29/2019 8:46:47 PM" 不匹配

  • HH 以 24 小时格式表示一天中的小时,而您的输入使用 12 小时格式。

  • 您输入中的PM 未在格式字符串中表示;使用tt 来笼统地表示 AM / PM 说明符。

  • 您使用空格分隔日期组件,而输入字符串使用/

  • 您的格式字符串指定了一个位月份组件(MM;例如,05),而输入只有一个数字(5)。

因此,您应该使用以下内容:

PS> [datetime]::ParseExact('5/29/2019 8:46:47 PM','M/d/yyyy h:mm:ss tt', [cultureinfo]::InvariantCulture)

Wednesday, May 29, 2019 8:46:47 PM

注意使用[cultureinfo]::InvariantCulture 而不是$null,因为后者将默认为当前 文化,这意味着在使用本地化 AM/PM 指示符的文化中调用可能会失败(例如例如,在越南文化 (vi-VN) 中,指示符是 SA / CH)。

当然,您也可以使用适当的特定文化,例如 en-US(英语(美国))(或假设您的代码永远不会在任何其他文化活动的情况下运行)。


顺便说一句,请注意即使格式字符串中的/: 也不是文字:它们代表特定于文化的日期和时间分隔符,分别。

要将它们视为文字,您必须使用嵌入式引用;例如,/ 将被引用为 '/''"/"\/

演示非字面解释:

PS> [datetime]::ParseExact('6.2019','M/yyyy', [cultureinfo] 'de-DE')

Saturday, June 1, 2019 12:00:00 AM

注意/ 如何匹配适合区域性的日期分隔符.

虽然在 输出 格式中始终使用适合区域性的分隔符,但在 解析 期间 - 作为礼貌 - @987654355 的 文字 解释@ 和 : 被用作 fallback 机制:

# Works too - "/" is also recognized as a literal.
PS> [datetime]::ParseExact('6/2019','M/yyyy', [cultureinfo] 'de-DE')

Saturday, June 1, 2019 12:00:00 AM

【讨论】:

    【解决方案2】:

    尝试其中一种。

    ($stringToDatetime1 = '5/29/2019 8:46:47 PM' | Get-Date)
    Wednesday, May 29, 2019 8:46:47 PM
    
    ($stringToDatetime2 = [DateTime]::ParseExact('5/29/2019 8:46:47 PM','M/d/yyyy h:mm:ss tt',$null))
    Wednesday, May 29, 2019 8:46:47 PM
    
    ($stringToDatetime3 = [Datetime]'5/29/2019 8:46:47 PM')
    Wednesday, May 29, 2019 8:46:47 PM
    

    顺便说一句,此错误已在此处完整记录:

    PowerShell [DateTime] throws the error “String was not recognized as a valid DateTime.”

    【讨论】:

    • 谢谢大家 - ($stringToDatetime2 = [DateTime]::ParseExact('5/29/2019 8:46:47 PM','M/d/yyyy h:mm:ss tt', $null)) 为我工作。我现在明白了。
    【解决方案3】:
    PS /Users/js> [DateTime]'5/29/2019 8:46:47 PM'
    
    Wednesday, May 29, 2019 8:46:47 PM
    
    
    PS /Users/js> ([DateTime]'5/29/2019 8:46:47 PM').gettype()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     DateTime                                 System.ValueType
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      • 2015-09-17
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      相关资源
      最近更新 更多