We could always do this.
001
|
New-Object DateTime ( 2015, 10, 31 )
|
With PowerShell 5, they added the static ::New() method to every .Net class. (This was done at the PowerShell level. This method does not exist natively in .Net. PowerShell’s “Adaptive Type System” allows you to enhance any .Net definition, or even all of them.)
So now we can do this.
001
|
[DateTime]::New( 2015, 10, 31 )
|
At first glance, you might wonder why the PowerShell team resources weren’t used on something else. Anything else. But there is one thing that ::New() gives us that New-Object does not: discoverability of constructor definitions.
The ultimate resource for the method and constructor definitions (or “overloads”), for most .Net objects is MSDN.Microsoft.com. Just Google “MSDN datetime” (without the quotes) and there you are.
But that’s work. And I’m lazy. Plus sometimes all I need is just a quick cheat sheet for the object.
Method overloads (definitions)
For methods, we have long had a shortcut for getting a list of the overloads for a method and their syntax. Simply call the method WITHOUT parentheses.
This gives us the current date and time converted to a string in a default format based on my computer’s localization:
001
|
(Get-Date).ToString()
|
And this give us a list of the many .ToString() overloads that have been defined for datetime objects:
001
|
(Get-Date).ToString
|
-------------------
string ToString()
string ToString(string format)
string ToString(System.IFormatProvider provider)
string ToString(string format, System.IFormatProvider provider)
string IFormattable.ToString(string format, System.IFormatProvider formatProvider)
string IConvertible.ToString(System.IFormatProvider provider)
We’re not going to understand all of that without doing some research, and I suspect most of it is not helpful to us. But that second definition tells us that instead of accepting the default format, we can give it a string with a custom format specification. So after a little experimenting, we can create a name for a debug log like this.
001
|
(Get-Date).ToString( "'DebugLog.'yyyy.MM.dd-hh.mm.ss.'txt'" )
|
Constructor overloads
But constructor overloads have always been harder to get. They are buried deep in the type definition, and we can theoretically pull them out using PowerShell, but it isn’t pretty. And it’s work. And I’m lazy. With PowerShell 5, the work is all done for us.
Because the new ::New() method is a method, we can get the overloads using the same syntax as we did with .ToString(). Mostly. .ToString() is a dynamic method, so we call it from an instance of an object, using a period. ::New() is a static method, so we call it directly from the type definition, using two colons.
But the same parentheses rule still applies.
This will give us a new datetime object.
001
|
[DateTime]::New( 2015, 10, 31 )
|
This gives us the list of constructors for datetime objects, the different sets of parameters we can use with ::New() or New-Object to create a new datetime object. (In case you are just skimming the article, this is it. This is the useful thing you can use the new ::New() method for.)
001
|
[DateTime]::New
|
-------------------
datetime new(long ticks)
datetime new(long ticks, System.DateTimeKind kind)
datetime new(int year, int month, int day)
datetime new(int year, int month, int day, System.Globalization.Calendar calendar)
datetime new(int year, int month, int day, int hour, int minute, int second)
datetime new(int year, int month, int day, int hour, int minute, int second, System.DateTimeKind kind)
datetime new(int year, int month, int day, int hour, int minute, int second, System.Globalization.Calendar calendar)
datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond)
datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.DateTimeKind kind)
datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar)
datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar, System.DateTimeKind kind)
You can see, for example, why it would fail if you tried [datetime]::New() with no parameters. For DateTime objects, there is no constructor definition with no parameters.
Meanwhile, back at the ranch
Now even though we now have two (count them: two) different ways to do the exact same thing, we are not limited to just these two. We can also just tell PowerShell that we want an object to be a different type and it will do its best to oblige. In fact, it will try ten different ways to make the conversion happen, and trying to find an appropriate constructor in the target type definition is only one of them.
The following works despite not having a matching constructor. (The precise interpretation of the string will depend on your computer’s localization settings.)
001
|
[DateTime]'10/12/15'
|
No comments:
Post a Comment