1

Why it is like we get different DateTime formats (especially for date separators slash vs hyphen) without using any custom formats when printed on the console and written to a file.

Even when using the same Dotnet's System.DateTime.Now, I am seeing the difference in the output of C# vs PowerShell.

Following are my observations for C# and Powershell:

C# - On Console

06-08-2018 02:01:11 AM

C# - written to a file

06-08-2018 02:02:32 PM

PowerShell - [System.DateTime]::Now - On Console

06 August 2018 01:54:45 AM

PowerShell - [System.DateTime]::Now.ToLocalTime() - On Console

06 August 2018 01:54:53 AM

PowerShell - Get-Date - On Console

06 August 2018 01:54:57 AM

PowerShell - [System.DateTime]::Now - written to a file

08/06/2018 01:46:35

I am mostly curious about when written to a file case of both C# and PowerShell as observed in the same system.

One more point to be noted - I have also seen the C#'s hyphen getting changed into slash on a different system when running the same exe. I am not sure why this happens and due to this it caused some exceptions. I had to use explicit DateTime format to overcome this problem.

Are there any best practices when dealing with DateTime formats?

======================== UPDATE ====================================

As per suggested by @mjwills:

I found that when explicitly using the Tostring() in PowerShell, the behavior becomes consistent in C# and Powershell even if written to a file through PowerShell.

[System.DateTime]::Now.ToString()
Koder101
  • 844
  • 15
  • 28

2 Answers2

2

C# will by default convert DateTime to string by calling ToString (which generally results in short-date and long-time format).

Powershell doesn't do that. As per the docs:

By default, the date-time is displayed in long-date and long-time formats for the system locale.

If you want a consistent, explicit format when outputting DateTime as string then you must always use an explicit date and time format string (e.g. https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings).

mjwills
  • 23,389
  • 6
  • 40
  • 63
  • 2
    C# and Powershell are using two different techniques for converting `DateTime` to `string`. So, in effect, they output different things because they aren't running the 'exact same' code. – mjwills Aug 05 '18 at 21:33
2

An implicit call to .ToString() is made when you pass a System.DateTime instance to Console.WriteLine() from a C# program.

By contrast, PowerShell has its own output-formatting system, described in Get-Help about_Format.ps1xml:

  • Output formats are selected by data type of objects being output.
  • Frequently used .NET types have predefined formats.

    • In the case at hand, System.DateTime, the output format is defined here.
      • With a default System.DateTime instance, this amounts to (assuming $dt as the instance at hand):
        "{0} {1}" -f $dt.ToLongDateString(), $dt.ToLongTimeString()
  • However, in the absence of an output-format definition for a given type, PowerShell does fall back on .ToString().


If you want consistent output in both cases, call .ToString() explicitly in PowerShell:

(Get-Date).ToString()

Caveat:

  • .ToString() outputs a representation that is formatted based on the current culture, if supported by the type.

  • By contrast, when PowerShell uses implicit stringification, such as in the context of expandable strings (strings with interpolation, "..."; e.g., "$(Get-Date)") it always applies the invariant culture, by design - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775