Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTime.TryParse produces different results in different environments #25120

Closed
Petermarcu opened this issue Feb 21, 2018 · 11 comments
Closed

Comments

@Petermarcu
Copy link
Member

@Doff3n commented on Wed Feb 14 2018

DateTime.TryParse produces different results in different environments

General

I am trying to parse a date, with DateTime.TryParse and with a provided Norwegian culture and no DatetimeStyles:

var result: DateTime.TryParse("29.01", new CultureInfo("nb-NO", false), DateTimeStyles.None, out var parsedDateTime)

I am purposely sending in "29.01" and expecting the result to parse to a default Datetime: "29.01.2018",
I also expect that 29.01.18 and 29.01.2018 parses to the correct dates.

In norway the date format is dd.MM.YYYY HH:mm
Code:
https://github.com/Doff3n/HelloDate

Commands:

  • dotnet build
  • dotnet run

Running this on my PC:

  • dotnet run
    parsedDateTime: 29.01.2018 00:00:00
    result: True

Running this on the VM:

  • dotnet run
    parsedDateTime: 01.01.0001 00.00.00
    result: False

.Net core sdk version: 2.1.4, runtime: 2.0.5

In desperation I have also tried setting Date and Time formats in Windows, but I would have expected the property UseUserOverride: false to not allow user settings.

@danmoseley
Copy link
Member

@Doff3n what are the configurations of your host and VM? Both the same Windows version?

@Doff3n
Copy link

Doff3n commented Feb 22, 2018

Localhost/my PC:
OS Name Microsoft Windows 10 Enterprise
Version 10.0.16299 Build 16299
System Type x64-based PC
IISExpress

VM:
OS Name Microsoft Windows Server 2016 Standard
Version 10.0.14393 Build 14393
System Type x64-based PC
IIS 10.0.14393.0

@Doff3n
Copy link

Doff3n commented Feb 22, 2018

I am not sure what configurations to set here.
As I am using useUserOverride = false I expect that the culture is set equally on both machines even with user configurations. But it is hard to find out what this override really does.

@tarekgh
Copy link
Member

tarekgh commented Feb 22, 2018

@Doff3n on your VM, are you sure TryParse returned true?

would be nice too if you can get the output of the following lines on the 2 machines

            foreach (string s in new CultureInfo("nb-NO", false).DateTimeFormat.GetAllDateTimePatterns())
            {
                Console.WriteLine(s);
            }

@Doff3n
Copy link

Doff3n commented Feb 23, 2018

I wrote a console app and built it on the VM, this produces the following different results

Localhost output VM output
dd.MM.yyyy dd.MM.yyyy
d. MMM yyyy d. MMM yyyy
dddd d. MMMM yyyy dddd d. MMMM yyyy
d. MMMM yyyy d. MMMM yyyy
dddd d. MMMM yyyy HH:mm
dddd d. MMMM yyyy HH.mm dddd d. MMMM yyyy HH.mm
d. MMMM yyyy HH:mm
d. MMMM yyyy HH.mm d. MMMM yyyy HH.mm
dddd d. MMMM yyyy HH:mm:ss
dddd d. MMMM yyyy HH.mm.ss dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH:mm:ss
d. MMMM yyyy HH.mm.ss d. MMMM yyyy HH.mm.ss
dd.MM.yyyy HH:mm
dd.MM.yyyy HH.mm dd.MM.yyyy HH.mm
d. MMM yyyy HH:mm
d. MMM yyyy HH.mm d. MMM yyyy HH.mm
dd.MM.yyyy HH:mm:ss
dd.MM.yyyy HH.mm.ss dd.MM.yyyy HH.mm.ss
d. MMM yyyy HH:mm:ss
d. MMM yyyy HH.mm.ss d. MMM yyyy HH.mm.ss
d. MMMM d. MMMM
d. MMMM d. MMMM
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
ddd, dd MMM yyyy HH':'mm':'ss 'GMT' ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ddd, dd MMM yyyy HH':'mm':'ss 'GMT' ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
yyyy'-'MM'-'dd'T'HH':'mm':'ss yyyy'-'MM'-'dd'T'HH':'mm':'ss
HH:mm
HH.mm HH.mm
HH:mm:ss
HH.mm.ss HH.mm.ss
yyyy'-'MM'-'dd HH':'mm':'ss'Z' yyyy'-'MM'-'dd HH':'mm':'ss'Z'
dddd d. MMMM yyyy HH:mm:ss
dddd d. MMMM yyyy HH.mm.ss dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH:mm:ss
d. MMMM yyyy HH.mm.ss d. MMMM yyyy HH.mm.ss
MMMM yyyy MMMM yyyy
MMMM yyyy MMMM yyyy

Copied output localhost:
dd.MM.yyyy
d. MMM yyyy
dddd d. MMMM yyyy
d. MMMM yyyy
dddd d. MMMM yyyy HH:mm
dddd d. MMMM yyyy HH.mm
d. MMMM yyyy HH:mm
d. MMMM yyyy HH.mm
dddd d. MMMM yyyy HH:mm:ss
dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH:mm:ss
d. MMMM yyyy HH.mm.ss
dd.MM.yyyy HH:mm
dd.MM.yyyy HH.mm
d. MMM yyyy HH:mm
d. MMM yyyy HH.mm
dd.MM.yyyy HH:mm:ss
dd.MM.yyyy HH.mm.ss
d. MMM yyyy HH:mm:ss
d. MMM yyyy HH.mm.ss
d. MMMM
d. MMMM
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
yyyy'-'MM'-'dd'T'HH':'mm':'ss
HH:mm
HH.mm
HH:mm:ss
HH.mm.ss
yyyy'-'MM'-'dd HH':'mm':'ss'Z'
dddd d. MMMM yyyy HH:mm:ss
dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH:mm:ss
d. MMMM yyyy HH.mm.ss
MMMM yyyy

Copied output VM:
dd.MM.yyyy
d. MMM yyyy
dddd d. MMMM yyyy
d. MMMM yyyy
dddd d. MMMM yyyy HH.mm
d. MMMM yyyy HH.mm
dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH.mm.ss
dd.MM.yyyy HH.mm
d. MMM yyyy HH.mm
dd.MM.yyyy HH.mm.ss
d. MMM yyyy HH.mm.ss
d. MMMM
d. MMMM
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK
ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
yyyy'-'MM'-'dd'T'HH':'mm':'ss
HH.mm
HH.mm.ss
yyyy'-'MM'-'dd HH':'mm':'ss'Z'
dddd d. MMMM yyyy HH.mm.ss
d. MMMM yyyy HH.mm.ss
MMMM yyyy
MMMM yyyy

@Doff3n
Copy link

Doff3n commented Feb 23, 2018

.Net core runtime 1.0 is also installed on the VM, but the console app has
<TargetFramework>netcoreapp2.0</TargetFramework>

@tarekgh
Copy link
Member

tarekgh commented Feb 23, 2018

@Doff3n here is what I think happened: on the VM, TryParse failed (returned false and not true). which means the parsing is failed and you cannot depend on the return datetime.

The reason it failed is that on the VM, the default time pattern HH.mm while on the other machine it is HH:mm. so when parsing "29.01", the parser cannot know if to parse it as a date or parse as time because the date and the time separator are same ".".

your code should always use ParseExact to ensure the result. something like

var result: DateTime.TryParseExact("29.01", "dd.MM", new CultureInfo("nb-NO", false), DateTimeStyles.None, out var parsedDateTime)

Please, lat's know if this is not the case.

@Doff3n
Copy link

Doff3n commented Feb 26, 2018

We are implementing a simple string filter, so we were expecting not to know the date format, but support a range of formats

@joperezr
Copy link
Member

@tarekgh is this something we need to fix for 2.1?

@Doff3n
Copy link

Doff3n commented Feb 27, 2018

It looks like the VM only has the HH.mm format in Windows, while my PC has HH:mm in addition to HH.mm

@tarekgh
Copy link
Member

tarekgh commented Mar 1, 2018

We are implementing a simple string filter, so we were expecting not to know the date format, but support a range of formats

Expecting DateTime parsing to succeed with any string is the wrong assumption. the guidelines for parsing is either you pass the format pattern used with the date formatting or use invariant culture all the time for formatting and parsing. please try to fix your design according to that or handle the parsing failure when it happens.

It looks like the VM only has the HH.mm format in Windows, while my PC has HH:mm in addition to HH.mm

Globalization data can change between the different OS versions. so this is expected.

in summary, this is by design from the framework side.

@tarekgh tarekgh closed this as completed Mar 1, 2018
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.1.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants