Why does PowerShell always use US culture when casting to DateTime?
Asked Answered
D

2

16

When trying to read a CSV yesterday, I noticed that PowerShell seems to always assume US date format when using [datetime]"date".

My regional settings are all correct, and [DateTime]::Parse("date") uses the UK date format (dd/mm/yyyy).

Is this a bug, or a deliberate decision? If a deliberate decision, is this documented anywhere?

PS D:\> [DateTime]"12/10/2012"
10 December 2012 00:00:00

PS D:\> [DateTime]::Parse("12/10/2012")
12 October 2012 00:00:00

(Note: on a US machine, I expect these objects will be the same, but not so here on my machines in the UK).

Note: I don't want to change the format (it's a file from an external source), I don't want to format dates in output, I know I can use [DateTime]::Parse(). The question is the bit that ends with a ? :-)

Disjunction answered 16/1, 2013 at 12:58 Comment(0)
C
17

It is a deliberate decision. When casting a string to a DateTime you can use either the braindead US format or ISO 8601 – [datetime]'2012-10-12' works just fine and is much nicer to read.

The reason that this is limited and restricted is that scripts should not have a dependency on the current culture, at least for literals and quasi-literals (like casted strings). This is a major problem in writing robust batch files and you certainly don't want the same problems in PowerShell.

Lee Holmes has an explanation, which could be considered semi-official, as he is/was on the PowerShell team at MS:

To prevent subtle internationalization issues from popping into your scripts, PowerShell treats [DateTime] '11/26/2007' (a date constant) like a language feature – just as it does [Double] 10.5 (a numeric constant.) Not all cultures use the decimal point as the fractions separator, but programming languages standardize on it. Not all cultures use the en-US DateTime format, resulting in millions of internationalization bugs when people don’t consider the impact of having their software run in those cultures.

What Lee forgets to mention is what I wrote before, that the much more sensible ISO 8601 format works as well.

No documentation of this exists in either the PowerShell documentation or the Language Specification (v2), sadly. However, there is very little evidence that points to this being a bug.

Camp answered 16/1, 2013 at 13:0 Comment(10)
I thought it might be related to consistency across regions, but I can't find any official info on this. I actually think it's more confusing for the two to behave differently. Do you know of any documentation on what behaves differently like this?Disjunction
All casts behave this way. E.g. in my German locale [double]::Parse('1,2') and [double]'1,2' yield different results as well. As I said, I'd consider this not so much a drawback since you never want a script to fail due to such things with different locales. Using ::Parse makes things explicit like they should be in this case. In every language.Camp
I agree it may make sense (though I still think it's weird), but I can't find any official information on this, and I'd like to read it to see what other things might not work as I expect :(Disjunction
(note: in this case, it's a script for my own use on my own machine, so I made some assumptions. I agree that shared scripts should be more explicit, and this question is more about whether this is a documented "feature" than how to actually work around it).Disjunction
I'll try finding official docs on this in an hour or so. I remember at least the PowerShell Cookbook 2nd ed. mentioning how the typecast behaves for dates.Camp
A link to what @Camp talk about: leeholmes.com/blog/2009/01/13/…Nephograph
Indeed, good find. I even commented on that blog post ... exactly 4 years ago :D. I was actually going to dig out the specification, but Lee Holmes is (or at least was) a member of the PowerShell team, so his word probably has as much weight as Raymond Chen on Windows history or Eric Lippert on C#.Camp
@Christian Thanks, I had come across that one (a colleague showed me), but I still can't find any official documentation about this. Surely it exists? :/Disjunction
I'm not after "proof"; it's not that I don't "trust" Lee Holmes. I'd just like to read the docs around where this is, to see if there are other things that might behave differently. It seems like a fairly important thing to know, so there it must be mentioned in official help text somewhere?Disjunction
Danny, I've looked around a bit but couldn't find anything that could be considered official.Camp
D
1

You can force the culture for a single command if needed:

PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-US" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US"; [DateTime]::Parse("12/10/2012")

Monday, December 10, 2012 12:00:00 AM

PS C:\> [System.Threading.Thread]::CurrentThread.CurrentUICulture = "en-GB" ; [System.Threading.Thread]::CurrentThread.CurrentCulture = "en-GB"; [DateTime]::Parse("12/10/2012")

12 October 2012 00:00:00
Diadiabase answered 26/8, 2020 at 22:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.