.ToString()
will call the DateTime.ToString()
instance method which uses the current culture, where as casting will use whatever the PowerShell team decided to use for IFormatProvider
.
I believe the code in charge of this is LanguagePrimitives.ConvertTo
, which by the looks of it, they decided to use InvariantCulture
: LanguagePrimitives.cs#L1758C2-L1766.
# Both produce the same DateTime format string
[System.Management.Automation.LanguagePrimitives]::ConvertTo(
(Get-Date).AddDays(-3),
[string])
(Get-Date).AddDays(-3).ToString([cultureinfo]::InvariantCulture)
Type casting is actually handled by PSConvertBinder and they're also using InvariantCulture
there: Binders.cs#L3765-L3795. ScriptBlockDisassembler Module makes it really easy to understand what internal classes are being used:
PS ..\pwsh> { [string] [datetime]::Now } | Get-ScriptBlockDisassembly -Minimal
// ScriptBlock.EndBlock
try
{
funcContext._outputPipe.Add(
Fake.Dynamic<Func<CallSite, DateTime, string>>(PSConvertBinder.Get(typeof(string)))(DateTime.Now));
}
catch (FlowControlException)
{
throw;
}
catch (Exception exception)
{
ExceptionHandlingOps.CheckActionPreference(funcContext, exception);
}