PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.66k stars 7.08k forks source link

PowerShell 7.1 preview 3 doesn't use configured date/time format #12755

Closed sba923 closed 3 years ago

sba923 commented 4 years ago

This should speak for itself:

> $PSVersionTable.PSVersion.ToString(); (Get-ItemProperty 'HKCU:\Control Panel\International' -name sTimeFormat).sTimeFormat;  (Get-ItemProperty 'HKCU:\Control Panel\International' -name sShortDate).sShortDate; Get-Date -DisplayHint Time; Get-Date | ConvertTo-Csv
7.0.1
HH:mm:ss
yyyy-MM-dd

10:03:10
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 10:03:10","2020-05-22 00:00:00","22","Friday","143","10","Local","179","3","5","10","637257385901795718","10:03:10.1795718","2020"

> $PSVersionTable.PSVersion.ToString(); (Get-ItemProperty 'HKCU:\Control Panel\International' -name sTimeFormat).sTimeFormat;  (Get-ItemProperty 'HKCU:\Control Panel\International' -name sShortDate).sShortDate; Get-Date -DisplayHint Time; Get-Date | ConvertTo-Csv
7.1.0-preview.3
HH:mm:ss
yyyy-MM-dd

10:03:37 AM
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 10:03:37 AM","5/22/2020 12:00:00 AM","22","Friday","143","10","Local","61","3","5","37","637257386170614178","10:03:37.0614178","2020"

Steps to reproduce

Expected behavior

Time is formatted using 24-hr format, date using specified yyyy-MM-dd format.

Actual behavior

Time is formatted in 12-hr am/pm format, date using M/dd/yyyy format

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.0-preview.3
PSEdition                      Core
GitCommitId                    7.1.0-preview.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
vexx32 commented 4 years ago

Is this behaviour new in the latest preview or has it always been this way?

sba923 commented 4 years ago

I would say it's new in preview 3. Too bad, I've just upgraded my last system, so I don't have any preview 2 system anymore.

vexx32 commented 4 years ago

We'll need to confirm if there was a change at some point or if this is the original behaviour.

Also, can you confirm if this is affected at all by using the -UseCulture parameter explicitly?

iSazonov commented 4 years ago

We use Datetime.ToLongTimeString() method for output in the case. Also you could look (Get-Culture).DateTimeFormat.

sba923 commented 4 years ago

In 7.0.1:

> $PSVersionTable.PSVersion.ToString(); (Get-Culture).DateTimeFormat
7.0.1

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : -
FirstDayOfWeek                   : Monday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, MMMM d, yyyy HH:mm:ss
LongDatePattern                  : dddd, MMMM d, yyyy
LongTimePattern                  : HH:mm:ss
MonthDayPattern                  : MMMM d
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : yyyy-MM-dd
ShortTimePattern                 : HH:mm
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : MMMM yyyy
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed…}
ShortestDayNames                 : {Su, Mo, Tu, We…}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday…}
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr…}
MonthNames                       : {January, February, March, April…}
IsReadOnly                       : True
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr…}
MonthGenitiveNames               : {January, February, March, April…}

In 7.1 preview 3:

> $PSVersionTable.PSVersion.ToString(); (Get-Culture).DateTimeFormat
7.1.0-preview.3

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : /
FirstDayOfWeek                   : Sunday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, MMMM d, yyyy h:mm:ss tt
LongDatePattern                  : dddd, MMMM d, yyyy
LongTimePattern                  : h:mm:ss tt
MonthDayPattern                  : MMMM d
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : M/d/yyyy
ShortTimePattern                 : h:mm tt
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : MMMM yyyy
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed…}
ShortestDayNames                 : {S, M, T, W…}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday…}
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr…}
MonthNames                       : {January, February, March, April…}
IsReadOnly                       : True
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr…}
MonthGenitiveNames               : {January, February, March, April…}
sba923 commented 4 years ago

We'll need to confirm if there was a change at some point or if this is the original behaviour.

Also, can you confirm if this is affected at all by using the -UseCulture parameter explicitly?

> $PSVersionTable.PSVersion.ToString(); Get-Date | ConvertTo-Csv -UseCulture
7.0.1
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 19:33:59","2020-05-22 00:00:00","22","Friday","143","19","Local","174","33","5","59","637257728391742480","19:33:59.1742480","2020"

> $PSVersionTable.PSVersion.ToString(); Get-Date | ConvertTo-Csv -UseCulture
7.1.0-preview.3
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 7:34:45 PM","5/22/2020 12:00:00 AM","22","Friday","143","19","Local","63","34","5","45","637257728850632108","19:34:45.0632108","2020"
vexx32 commented 4 years ago

Looks like a regression indeed. @iSazonov do you know if there were any changes merged to this area of code since 7.1-p2? I can't recall any at the moment.

Perhaps it's a regression or change in .NET Core?

sba923 commented 4 years ago

Here's what I get with preview 2 on the same system:

> $PSVersionTable.PSVersion.ToString(); (Get-ItemProperty 'HKCU:\Control Panel\International' -name sTimeFormat).sTimeFormat;  (Get-ItemProperty 'HKCU:\Control Panel\International' -name sShortDate).sShortDate; Get-Date -DisplayHint Time; Get-Date | ConvertTo-Csv
7.1.0-preview.2
HH:mm:ss
yyyy-MM-dd

19:42:05
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 19:42:05","2020-05-22 00:00:00","22","Friday","143","19","Local","14","42","5","5","637257733250149958","19:42:05.0149958","2020"

> $PSVersionTable.PSVersion.ToString(); Get-Date | ConvertTo-Csv -UseCulture
7.1.0-preview.2
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","Friday, May 22, 2020 19:42:40","2020-05-22 00:00:00","22","Friday","143","19","Local","847","42","5","40","637257733608470239","19:42:40.8470239","2020"
iSazonov commented 4 years ago

I can not confirm. After I changed these format strings in registry and restarted PowerShell I get right outputs.

vexx32 commented 4 years ago

What? Where was changing the format strings in the registry mentioned here? 😕

sba923 commented 4 years ago

To get things right I uninstalled preview 3 and installed preview 2

😜

ghost commented 4 years ago

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

sba923 commented 4 years ago

I don't understand: there is an issue in preview 3, it has to be fixed!

iSazonov commented 4 years ago

I can repo. We need reliable repo steps. You could download zip packages, install PowerShell side-by-side, run both version and check result (better on clean system).

sba923 commented 4 years ago

You mean you can't repro?

I don't have a clean system to test on (could set up a test VM, but would take a significant amount of time).

I'll test with XCOPY-deployed SxS installations of preview 2 and preview 3.

sba923 commented 4 years ago

Here's the outcome, using these launch scripts:

REM runpwsh.bat
cls
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
.\pwsh -noprofile -file .\runtest.ps1
# runtest.ps1
$PSVersionTable.PSVersion.ToString()
(Get-ItemProperty 'HKCU:\Control Panel\International' -name sTimeFormat).sTimeFormat
(Get-ItemProperty 'HKCU:\Control Panel\International' -name sShortDate).sShortDate
Get-Date -DisplayHint Time
Get-Date | ConvertTo-Csv

image

image

Repro'ed on two different systems.

iSazonov commented 4 years ago

What is output:

$Host

(Get-Culture).DateTimeFormat

sba923 commented 4 years ago

On preview 2:

C:\tmp\PowerShell-7.1.0-preview.2-win-x64>PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem

C:\tmp\PowerShell-7.1.0-preview.2-win-x64>.\pwsh -noprofile -file .\runtest.ps1
7.1.0-preview.2

Name             : ConsoleHost
Version          : 7.1.0-preview.2
InstanceId       : 91f11a8e-5486-4058-b1e8-9bb93bb9adc9
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : -
FirstDayOfWeek                   : Monday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, MMMM d, yyyy HH:mm:ss
LongDatePattern                  : dddd, MMMM d, yyyy
LongTimePattern                  : HH:mm:ss
MonthDayPattern                  : MMMM d
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : yyyy-MM-dd
ShortTimePattern                 : HH:mm
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : MMMM yyyy
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed…}
ShortestDayNames                 : {Su, Mo, Tu, We…}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday…}
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr…}
MonthNames                       : {January, February, March, April…}
IsReadOnly                       : True
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr…}
MonthGenitiveNames               : {January, February, March, April…}

On preview 3:

C:\tmp\PowerShell-7.1.0-preview.3-win-x64>PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem

C:\tmp\PowerShell-7.1.0-preview.3-win-x64>.\pwsh -noprofile -file .\runtest.ps1
7.1.0-preview.3

Name             : ConsoleHost
Version          : 7.1.0-preview.3
InstanceId       : 9244eab6-c591-4b06-9148-719bc5cba22d
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : /
FirstDayOfWeek                   : Sunday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, MMMM d, yyyy h:mm:ss tt
LongDatePattern                  : dddd, MMMM d, yyyy
LongTimePattern                  : h:mm:ss tt
MonthDayPattern                  : MMMM d
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : M/d/yyyy
ShortTimePattern                 : h:mm tt
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : MMMM yyyy
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed…}
ShortestDayNames                 : {S, M, T, W…}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday…}
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr…}
MonthNames                       : {January, February, March, April…}
IsReadOnly                       : True
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr…}
MonthGenitiveNames               : {January, February, March, April…}
iSazonov commented 4 years ago

What is time you change the datetime format?

The PowerShell versions use different .Net 5 Preview - 3 and 4. You could download nightly build (it is on .Net 5.0 Preview5) and check again. If you will see the issue you could discuss this in .Net Runtime repo.

sba923 commented 4 years ago

I'm not sure I understand your question. When did I change the datetime format? That must've been when I installed the systems in the first place, 'cos as a software engineer I prefer 1) the English UI, so I changed the display language to English (my computers came with French Windows) 2) the ISO8601 YYYY-MM-DD date format. So I've probably never run any version of PowerShell with the default en-US date/time formats.

Where can I get the nightly builds from?

What is the .NET Core API that's used by PowerShell Core to convert a date/time to string? I need this information if I want to open an issue on .NET 5.0.

iSazonov commented 4 years ago

You can download night build from main page of the repository.

PowerShell uses Datetime.ToLongTimeString() method. All formats you get above with (Get-Culture).DateTimeFormat.

sba923 commented 4 years ago

On that main page, I can see the status of the nightly builds in CI, but no download links. Am I missing something?

I'll try creating a C# test program and run it with various previous versions of .NET 5.

iSazonov commented 4 years ago

Press on the status icon and look artifacts under "Build for Windows".

sba923 commented 4 years ago

Same repro:

image

vexx32 commented 4 years ago

The code that handles this is here:

https://github.com/PowerShell/PowerShell/blob/b1e998046e12ebe5da9dee479f20d479aa2256d7/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs#L1045-L1067

With this code in mind, can you check what you get back for (Get-Date).ToString() and (Get-Date).PSObject.ToString()?

I'm reopening this as it doesn't look like we've gotten to the bottom of it yet. 🙂

sba923 commented 4 years ago

image

image

image

sba923 commented 4 years ago

What's the easy way to create a C# program that invokes that .ToString() method and run it under various previews of .NET 5?

vexx32 commented 4 years ago

🤔 OK, that definitely looks like a regression in .NET 5 then, nice find.

Dunno if there's an easy way, but you can specify which preview to run against with usually a global.json in the project folder; you can see an example in the global.json in this repo. 🙂

If you can figure out which preview broke the ToString() behaviour, definitely worth opening up an issue on the dotnet/runtime repository so we can get that fixed.

iSazonov commented 4 years ago

You will save time if you discuss with .Net Runtime experts.

sba923 commented 4 years ago

That's what I want to do next... once I have found how to deploy the last 3 previews of .NET 5 side-by-side to run the C# test program against. I presume there are XCOPY-deployable zipfiles of those previews somewhere...

sba923 commented 3 years ago

Can someone help me find those .NET bits (at least the versions used by PS7.1 preview 2 and preview 3)?

sba923 commented 3 years ago

Maybe I'll just wait until preview 4, based on .NET 5 Preview 5, comes out, and test again there...

iSazonov commented 3 years ago

You can download nightly build - it is on .Net 5 Preview 5 already.

sba923 commented 3 years ago

Good news!

But... when I reach https://powershell.visualstudio.com/PowerShell/_build/results?buildId=55455&view=artifacts&type=publishedArtifacts I get:

image

and clicking artifacts doesn't do anything. What am I doing wrong?

Sorry for sounding dumb, I'm definitely a GH CI rookie...

iSazonov commented 3 years ago

You can load nightly build from main page https://github.com/PowerShell/PowerShell#build-status-of-nightly-builds

GitHub
PowerShell/PowerShell
PowerShell for every system! Contribute to PowerShell/PowerShell development by creating an account on GitHub.
sba923 commented 3 years ago

That's exactly what I've been trying to do, see Can't download PS nightly build.zip

iSazonov commented 3 years ago

Try "Artifacts" - button on the right.

sba923 commented 3 years ago

What "Artifacts" button on the right? Please refer to my PSR slideshow, or make a screenshot on your own.

I presume you wanted a ProcMon log of me reproducing the problem? Here it is, with preview 3.

runpwsh.bat.procmon.202006150911.PML.zip

iSazonov commented 3 years ago

@sba923 I still suggest to open new issue in .Net Runtime.

sba923 commented 3 years ago

That's what I've been aiming at for some time now, but I can't unless I can post a repro. For this, I need to know how to get a side-by-side deployment of different previews of .NET 5, and then write a C# program I would run against each of those .NET previews. I haven't been able to find out how to download and deploy those previews. Yet...

iSazonov commented 3 years ago

Download link https://dotnet.microsoft.com/download/dotnet/5.0?utm_source=dotnet-website&utm_medium=banner&utm_campaign=preview5-banner You can use install scripts from the link.

sba923 commented 3 years ago

Thanks for the hint.

But before I do this I'd like to test with a .NET 5 Preview 5-based build of PowerShell... ;-)

sba923 commented 3 years ago

I think this is it ;-)

using System;

namespace DateTimeToString
{
    class Program
    {
        static void Main(string[] args)
        {
            string dotnetversion = System.Environment.Version.ToString();
            Console.WriteLine("dotnet version: {0}", dotnetversion);
            var now = System.DateTime.Now;
            string str = now.ToString();
            Console.WriteLine("DateTime.Now.ToString(): {0}", str);
        }
    }
}
gci -dir 'dotnet5p*' | % {
        $dotnetdir = $_.FullName
        "Testing in: " + $dotnetdir
        & ($dotnetdir + '\dotnet') --info | sls -raw 'Version:.*preview'
        & ($dotnetdir + '\dotnet') ($dotnetdir + '\DateTimeToString.dll')
}

image

sba923 commented 3 years ago

Opened https://github.com/dotnet/runtime/issues/37897

iSazonov commented 3 years ago

In procmon log I see an access to ICU - I guess the issue could be related to the fact.

iSazonov commented 3 years ago

It seems .Net has an option to opt out ICU. You could try and see a result.

sba923 commented 3 years ago

Here's what I get with "System.Globalization.Invariant": true if this is what you were referring to:

image

Formatting is incorrect whatever the .NET 5 preview version.

iSazonov commented 3 years ago

No, there is an option to switch back from ICU to Windows traditional API.

iSazonov commented 3 years ago

See https://docs.microsoft.com/en-us/dotnet/core/run-time-config/globalization#nls

Globalization config settings - .NET Core
Learn about run-time settings that configure globalization aspects of a .NET Core app, for example, how it parses Japanese dates.
sba923 commented 3 years ago

Will test... The change to use ICU was introduced in .NET 5 preview 4...