日期转换使用不同的计算机语言出错 [英] Date conversion going wrong with different computer language
问题描述
我写了一个Powershell脚本来为客户计费.我得到账单清单,检测月份并得到那个特定账单.时间戳记采用Unix格式,因此在某种程度上我会根据系统语言弄乱转换内容.
I wrote a Powershell script for billing of customers. I get the list of bills, detect the month and get that specific bill. The timestamps are in Unix format and somehow I mess something up in the conversion depending on system language.
例如: $ FirstDayPrevMonth =(获取日期-第1天-小时0-分钟0-秒0-毫秒0).Addmonths(-1)
对于以下返回的系统,转换失败:zondag 2020年11月1日00:00:00.对于返回以下内容的系统,转换成功:2020年11月1日,星期日,12:00:00 AM
The conversion fails for systems that return: zondag 1 november 2020 00:00:00. The conversion succeeds for systems that return: Sunday, November 1, 2020 12:00:00 AM
我从账单列表中获得的时间戳例如是:1604188800000
The timestamp I get from the bills list is for example: 1604188800000
我运行以下函数并传递1604188800000,该函数应返回月份号:
The I run the following function passing 1604188800000, which should return number of the month:
Function Convert-FromUnixDateToMonth ($UnixDate) {
(get-date( [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').Addmilliseconds($UnixDate)).ToString("MM/dd/yyyy") ) ) -as [int] ### -UFormat %m
}
英语系统的结果为11(正确),荷兰语系统的结果为1(错误).我知道它在语言设置中的某个位置,但是我只是想不出如何更改它,因此它可以独立于语言工作.
The result for the english system is 11 (correct), for the Dutch system is 1 (incorrect). I know it is somewhere in the language setting but I just can't figure out how to change this so it would work independent of the language.
推荐答案
没有理由涉及时间戳的 string 表示形式;正如您所经历的,除了放慢脚步之外,还有特定于文化的解释的陷阱(请参阅下一节):
There is no reason to involve string representations of timestamps; apart from slowing things down, there's the pitfall of culture-specific interpretation, as you've experienced (see next section):
最简单的解决方案是使用类型 [datetimeoffset]
( System.DateTimeOffset
):
The simplest solution is to use type [datetimeoffset]
(System.DateTimeOffset
):
# Returns 11 - the month index - in all time zones *at or ahead of* UTC.
[datetimeoffset]::FromUnixTimeMilliseconds(1604188800000).LocalDateTime.Month
解决方案尝试的更正版本:
A corrected version of your solution attempt:
[timezone]::CurrentTimeZone.ToLocalTime(
([datetime] '1/1/1970').AddMilliSeconds(1604188800000)
).Month
-
请注意,在 this 情况下,由于使用 cast .
您不需要致电完全是
Get-Date
,这是由于传递日期的 string 表示法而引起的问题-请参见下一部分.You didn't need a call to
Get-Date
at all, which is where the problem arose due to passing a string representation of a date - see next section.顺便说一句,
Get-Date -Date
直接直接接受[datetime]
实例,因此无需传递字符串.Incidentally,
Get-Date -Date
directly accepts a[datetime]
instance, so there's no need for to pass a string.- When you do pass a string, the resulting
[datetime]
(System.DateTime
) has a.Kind
property value ofUnspecified
rather thanLocal
具体地说,您在不同上下文中的字符串类型转换中遇到了问题不一致:
Specifically, you've run into a problematic inconsistency in from-string type conversions in different contexts:
-
Casts 和 script/function 参数使用 culture- 不变 从字符串转换;也就是说,不管当前的文化是什么(反映在
$ PSCulture
中),所谓的 first 令牌11
被解释为 month .
Casts and script/function parameters use culture-invariant from-string conversion; that is, irrespective of what the current culture is (as reflected in
$PSCulture
), the rules of the so-called invariant culture are used, whose date formats are based on the US-English culture; therefore, for instance,[datetime] '11/10/2000'
is always interpreted as "10 November 2000", i.e., the first token,11
, is interpreted as the month.
- 但是,也支持更多的国际友好格式;例如,
[datetime]'2000-11-10'
与上述等效.
- However, more international-friendly formats are supported too; e.g.,
[datetime] '2000-11-10'
is the equivalent of the above.
出乎意料的是, cmdlet 参数使用 culture- 敏感 从字符串转换.
Unexpectedly, cmdlet parameters use culture-sensitive from-string conversion.
- This discrepancy is a known problem, but it was decided not to fix it, so as not to break backward compatibility - see GitHub issue #3348.
这篇关于日期转换使用不同的计算机语言出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- When you do pass a string, the resulting