Converting String To Date Not Working

I have date values retrieved as string objects from wbadmin get version command on a Windows 2008 server. When I try to convert them to datetime objects the conversion fails at those strings that have their days higher than 12. My region date format is dd-MM-yyyy which is how the wbadmin command formatted the string. Powershell however is refusing to accept this format as valid for conversion.

Any ideas p

July 22nd, 2015 5:54am

Hi,

well ... this is working just fine for me:

Get-Date -Date "17-12-2014"

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
July 22nd, 2015 6:08am

I suspect if you run these commands you will see a similar output:

PS C:\powershell> [System.Globalization.CultureInfo]::CurrentCulture

LCID             Name             DisplayName                                                                                                                                               
----             ----             -----------                                                                                                                                               
2057             en-GB            English (United Kingdom)                                                                                                                                  



PS C:\powershell> [System.Globalization.CultureInfo]::CurrentuiCulture

LCID             Name             DisplayName                                                                                                                                               
----             ----             -----------                                                                                                                                               
1033             en-US            English (United States)  

You may need to parse the date to get powershell to accept it as a valid datetime object - 

[datetime]::Parse(<yourdate>, [System.Globalization.CultureInfo]::GetCultureInfo("En-GB"))

July 22nd, 2015 6:17am

Hi,

well ... this is working just fine for me:

Get-Date -Date "17-12-2014"

Cheers,

Free Windows Admin Tool Kit Click here and download it now
July 22nd, 2015 6:25am

I suspect if you run these commands you will see a similar output:

PS C:\powershell> [System.Globalization.CultureInfo]::CurrentCulture

LCID             Name             DisplayName                                                                                                                                               
----             ----             -----------                                                                                                                                               
2057             en-GB            English (United Kingdom)                                                                                                                                  



PS C:\powershell> [System.Globalization.CultureInfo]::CurrentuiCulture

LCID             Name             DisplayName                                                                                                                                               
----             ----             -----------                                                                                                                                               
1033             en-US            English (United States)  

You may need to parse the date to get powershell to accept it as a valid datetime object - 

[datetime]::Parse(<yourdate>, [System.Globalization.CultureInfo]::GetCultureInfo("En-GB"))

On the contrary, mine was United States for both
July 22nd, 2015 6:54am

That makes sense, the date format for the US culture is mm/dd/yyyy (or variations of -[System.Globalization.CultureInfo]::GetCultureInfo("En-us").DateTimeFormat.GetAllDateTimePatterns() will get you them all), using .net to create a datetime wouldn't allow for the day to come first without parsing or providing the format.

I had always assumed get-date just used .net under the hood but it must work differently.  

Free Windows Admin Tool Kit Click here and download it now
July 22nd, 2015 9:11am

US = mm-dd-yyyy
Gb = dd-mm-yyyy

In US "17-12-2002"  won't work because 17 is not a legal month.  By Using Gb formats  we get the correct parse order.

IF you have CurrentCulture set to en-Gb then Get-Date or [datetime] will work correcty for this date.

July 22nd, 2015 9:28am

That's what I said.

I have encountered issues with the CurrentCulture being set to En-Gb and the CurrentUI culture being to set to En-Us, in those cases the date still needed to be parsed before it would be displayed in the Gb format when using [datetime], get-date -date works as expected though. 

Free Windows Admin Tool Kit Click here and download it now
July 22nd, 2015 9:54am

US = mm-dd-yyyy
Gb = dd-mm-yyyy

In US "17-12-2002"  won't work because 17 is not a legal month.  By Using Gb formats  we get the correct parse order.

IF you have CurrentCulture set to en-Gb then Get-Date or [datetime] will work correcty for this

July 24th, 2015 8:44am

Furthermore, could someone explain to me the difference between the settings retrieved by each of the following:

Get-Culture

Get-UICulture

[System.Globalization.CultureInfo]::CurrentCulture

[System.Globalization.CultureInfo]::CurrentUICulture

And additionally, which of these is the default Windows System Culture?

My questions stem from some strange discoveries on my servers.

The Windows 2008 server at the centre of this post has the DateTimeFormat settings of each of the above exactly the same (day before month) despite the CurrentCulture and CurrentUICulture being US, yet [DateTime]"23/1/2015" will throw an error.

MSDN says:

"Unless it is set explicitly, the value of the DefaultThreadCurrentCulture property is null, and the culture of threads in an application domain that have not been assigned an explicit culture is defined by the default Windows system culture"

Given that I confirmed the server's DefaultThreadCurrentCulture property to be null, why does the casting of the string to date fail?

I then have another Windows 2012 server that returns Gb as its culture when I run the command locally but returns US when I run it remotely.

Can anyone explain these things to me pls.

Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 10:56am

It is notPowerShell that is at fault.  It is you understanding of how this works.  The UI is based on culture selection.  THe display format does not affect the way dates are interpreted.   Work that out and you willsee there is more to this.

July 24th, 2015 1:10pm

Start by inspecting oth oof thiese very carefully:

(Get-Culture).DateTimeFormat

(Get-UICulture).DateTimeFormat

Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 1:22pm

It is notPowerShell that is at fault.  It is you understanding of how this works.  The UI is based on culture selection.  THe display format does not affect the way dates are interpreted.   Work that out and you willsee there is more to this.

July 24th, 2015 1:31pm

CultureInfo affects how time is displayed.  How time is converted is a default parse and requires an explicit culture be chosen.  The parser parses times based on a best guess mechanism.  All variations cannot be given equal weight,  Pick a culture and you will get the correct answer.

Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 1:35pm

CultureInfo affects how time is displayed.  How time is converted is a default parse and requires an explicit culture be chosen.  The parser parses times based on a best guess mechanism.  All variations cannot be given equal weight,  Pick a culture and you will get the correct answer.

July 24th, 2015 5:15pm

Start by inspecting oth oof thiese very carefully:

(Get-Culture).DateTimeFormat

(Get-UICulture).DateTime

Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 5:44pm

Using a default cast does not call parse.  It calls the default constructor.  Calling "Parse" implicitly uses a static method to create a datetime object and is not a cast.

[datetime]'23/1/2001'  is a cast
[datetime]::Parse(...)   is a call too a static method.

See: https://msdn.microsoft.com/en-us/library/1k1skd40(v=vs.100).aspx

Also [datetime] is a structure and not a type. 

So always check the current thread culture timeinfo.

July 24th, 2015 5:46pm

There are two other issue that I do not want to take the time to test.

In US the version of Windows is US.  In Europe it is MUI I believe.  This would have an impact on PowerShell.

Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 5:52pm

Forgive my never ending questions yet again jrv. I am always either learning new and right or unlearning bad; either way I am good.

By default cast which you say calls the default constructor, is that not a public parameterless instance constructor for a class or type?

My understanding is that it is a special method of a class or type that instantiates a new copy with base property values where none are supplied or not required.

Foe example, $NewVersionVariable = New-Object System.Version created a new instance of theSystem.Version object on my PC in $NewObj variable with the values:

Major  Minor  Build  Revision
-----  -----  -----  --------
0      0      -1     -1

I never supplied the ArgumentList parameter with values, the default constructor did, or is that not so? Please correct me if I am wrong. I really want to be sure my understanding of these things are sound.

Similarly, $NewDateVariable = New-Object System.DateTime gave me a $NewDate variable ofDateTime type with a value of January 1, 0001 12:00:00 am on my PC

.Net MSDN specifically advised against default constructors for structure type like DataTime until this year's release as some compilers (C#, VB, F#) did not support it. Which may be thee reason why Powershell will not regard creating a variable without explicitly initializing it. In other words, the following will fail:

[System.Version]$NewVersionVariable

[System.DateTime]$NewDateVariable

Powershell will recognize the variables only if they are initialized by definite value assignment that it can cast by the accelerator

Moreover, of all the 11 instance constructors of DateTime, there is none that takes a string input. So there is no way casting can occur by constructor where a string parameter is provided.

See: DateTime Structure

With [DateTime]"23/1/2015" , I am not creating a new instance of an object, rather I am converting a string value - "23/1/2015" - to a DateTime object

I must then ask if there really is a difference between casting and conversion? I thought casting is just a technical word for conversion from one type to another. It simply describes the act of the conversion not the means or mode. Parsing however is just one of the modes of conversion. In fact, Parse conversion (conversion based on Parse() method defined in the destination type) is said to be preferred by Powershell before Cast conversion (conversion by an implicit or explicit cast operator) and also before Constructor conversion. So even if powershell will use a constructor of [DateTime] to a string, it will be AFTER it has attempted its Parse() method and failed.

[DateTime]::Parse(...) is indeed a call to a static method. But to do what? To convert, which is still casting, the difference now is just that I am explicit about HOW the casting is done. In other words I am manually casting by calling a static method of the DateTime class.

Scripting Guys Blog says [datetime]"1/2/14 is using [DateTime] type accelerator

[psobject].Assembly.GetType("System.Management .Automation.TypeAccelerators")::get is a command that retrieves list of Type Accelerator in Pwershell and [DateTime] is of those listed

See: Convert String into DateTiime object

So how is [DateTime] not then a type? I am rather confused when you say it is a structure and not a type. MSDN says a structure is a value type. .Net types are either value types or reference types

See: Structure and Common Type System

July 25th, 2015 3:37am

From your other thread I think you have the ful answer.  I was wrong about the default constructor.  System.DateTime does not have a constructor that takes a string.  What we have learned (I have learned) is that PowerShell overrides this and provides a consistent programming interface.  THis is, according to Lee Holmes, PowerShell has decided to avoid programming issues by standardizing programming dates on ISO 8601 format (US) as has most of the world.

Read this in its entirety including the links:  http://stackoverflow.com/questions/14359053/why-does-powershell-always-use-us-culture-when-casting-to-datetime

It makes sense to me and I think you, too, will understand it.

Free Windows Admin Tool Kit Click here and download it now
July 25th, 2015 4:00am

Thanks a lot  jrv for engaging me and being patient. I have my answers and my reservations as expressed in my other post.
July 25th, 2015 6:16pm

Just thought I should add this workaround for someone

As an advice to persons using DMY date format, to ensure Powershell always interprets your date literals correctly, always pass your month value as name word rather than numbers. The full month name - January, February, March, etc., or their 3-letter abbreviations - Jan, Feb, Mar, etc will never fail.

[DateTime]"12May2015"
[DateTime]"12/May/2015"
[DateTime]"12 May 2015
[DateTime]"12-May-2015"
[DateTime]"12 Feb, 2015"
[DateTime]"12 February 2015"

All the above will be interpreted correctly as intended even though MDY format is always assumed by Powershell.

And where [DateTime]"22/05/2015" will throw an error of invalid datetime, [DateTime]"22/May/2015" will succeed

Free Windows Admin Tool Kit Click here and download it now
July 28th, 2015 4:27am

The problem is not one of convenience.  it is one of having a standard that works everywhere. Look at the battle over HTML5. Every company in the world wanted to enshrine their HTML technology. In the end a single choice was made.

We  have to choose to drive on one specific side of the road.  Science and technology require us to make choices.

July 28th, 2015 7:20am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics