Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get-Date cast to string vs ToString()

My understanding of PowerShell's string embedding syntax "$($object)" has always been that $object is cast to [System.String], which invokes $object.ToString(). However, I've noticed this curious behavior with the [DateTime] class using PowerShell 4.0 on Windows 8.1.

PS> $x = Get-Date

PS> $x.GetType() | select -ExpandProperty Name
DateTime

PS> $x.ToString()
2015-05-29 13:36:06

PS> [String]$x
05/29/2015 13:36:06

PS> "$($x)"
05/29/2015 13:36:06

It seems that "$($object)" gives the same behavior as casting to string, but is clearly producing a different result from $object.ToString(). $x.ToString() is consistent with the short date format set in intl.cpl (yyyy-MM-dd). [String]$x appears to use the en-US default.

It is possible this is simply a bug in the DateTime class, but I'm more surprised that the different methods of converting an object to a string produce different results. What are the rules for casting an object to a string, if not calling ToString()? Is the DateTime class simply a special case because of its overloading of ToString(String)?

like image 764
Ryan Bemrose Avatar asked May 29 '15 21:05

Ryan Bemrose


People also ask

What is the difference between convert to string and toString method?

Here both the methods are used to convert the string but the basic difference between them is: "Convert" function handles NULLS, while "i. ToString()" does not it will throw a NULL reference exception error. So as good coding practice using "convert" is always safe.

Is toString a casting?

String Type Casting and the toString() Method Using the (String) syntax is strictly connected with type casting in Java.

Which of the following is true about .toString and convert toString ()?

Convert. ToString() handles null , while ToString() doesn't. Save this answer.


1 Answers

If an object implements the IFormattable interface, then PowerShell will call IFormattable.ToString instead of Object.ToString for the cast operation. A similar thing happens for static Parse method: if there is an overload with IFormatProvider parameter, then it would be called.

Add-Type -TypeDefinition @'
    using System;
    using System.Globalization;
    public class MyClass:IFormattable {
        public static MyClass Parse(string str) {
            return new MyClass{String=str};
        }
        public static MyClass Parse(string str,IFormatProvider fp) {
            return new MyClass{String=str,FormatProvider=((CultureInfo)fp).DisplayName};
        }
        public string String {get;private set;}
        public string FormatProvider {get;private set;}
        public override string ToString() {
            return "Object.ToString()";
        }
        string IFormattable.ToString(string format,IFormatProvider fp) {
            return string.Format("IFormattable.ToString({0},{1})",format,((CultureInfo)fp).DisplayName);
        }
    }
'@
[String](New-Object MyClass) #Call IFormattable.ToString(null,CultureInfo.InvariantCulture)
[MyClass]'Test'              #Call MyClass.Parse("Test",CultureInfo.InvariantCulture)
like image 110
user4003407 Avatar answered Oct 05 '22 23:10

user4003407