关于日期时间:Powershell 将字符串转换为 mmddyyyy 格式的最干净方法

Powershell Cleanest way to convert a string to mmddyyyy format

提前谢谢你...

我有字符串输出:

1
2021-12-23

字符串 Base.Type 是 System.Object

我想把它转换成:

1
12-23-2021

1
12/23/2021

有什么想法吗?


注意:此问题与将日期格式从"yyyymmdd"更改为"mm/dd/yyyy"几乎重复;虽然两者密切相关,但这个问题更公开地关注使用不同格式从字符串解析为日期,然后再解析为字符串;相比之下,链接问题的 from 方面是问题的附带部分。

Bali C 在对该问题的评论中提出了最简洁的解决方案,只需稍作调整即可:

1
2
3
# Note the""-escaped separators - see below.
PS> Get-Date -Date 2021-12-23 -Format dd\\-MM\\-yyyy # or dd\\/MM\\/yyyy
23-12-2021

这将适用于大多数文化,因为格式 yyyy-MM-dd(如示例输入字符串 '2021-12-23' 所示)是除少数文化外的所有文化中公认的格式。

PowerShell 通常会尝试使用不变的区域性以使代码在不同区域中同样工作,但在 cmdlet 参数的情况下实际上是区域性敏感的,这是一个历史事故,如果不破坏向后兼容性就无法修复。

请参阅下面的真正文化不变的解决方案,这也解释了为什么要使用分隔符。 -/ 应该被转义以获得最大的鲁棒性。

由于 PowerShell 的转换使用不变的文化和格式 yyyy-MM-dd(如示例输入字符串 '2021-12-23' 所示)恰好是该文化中公认的格式,您可以简单地:

  • 将您的字符串转换为 [datetime] 以创建一个 System.DateTime 实例
  • 然后使用所需的格式字符串调用 .ToString() 以生成所需的字符串格式,如该问题的许多答案所示。

无论有效的特定文化如何,以下内容都应该有效:

1
2
3
4
5
PS> ([datetime] '2021-12-23').ToString('MM\\-dd\\-yyyy')
12-23-2021

PS> ([datetime] '2021-12-23').ToString('MM"/"dd"/"yyyy')
12/23/2021

注意分隔符。 -/ 被转义/引用,以表明它们将被逐字使用(您可以在 \\-转义和嵌入引用之间自由选择)。

这是必要的,因为像 / 这样的字符在默认情况下被解释为适合区域性的日期分隔符的占位符,例如,因此 - 根据有效的区域性(如 $PSCulture 中所反映的那样) - 它们可能被翻译成不同的字符,例如 .,例如。

如果您的原始字符串表示在不变的文化中未被识别,您可以在调用 .ToString() 之前使用 System.DateTime.ParseExact 将输入字符串解析为 [datetime] (System.DateTime) 实例,如上所述:

1
2
3
4
5
[datetime]::ParseExact(
  '2021-12-23',
  'yyyy\\-MM\\-dd',
  $null  # current culture
).ToString('MM"-"dd"-"yyyy')

以上再次产生 '12-23-2021'.

请注意,由于使用了 $null,当前的区域性用于解析,但是在这种情况下没有任何效果,因为分隔符是字符。使用嵌入式引用,并且只涉及数字,而不是(与文化相关的)名称,例如月份名称。

如果您确实需要特定文化的上下文,请传递 [cultureinfo] 实例 (System.Globalization.CultureInfo) 而不是 $null;例如,要在法国(法国)文化的上下文中解析,请传递 [cultureinfo] 'fr-FR'.