Bug 56658 - AbbreviatedMonthNames incompatibility causes parsing failures
Summary: AbbreviatedMonthNames incompatibility causes parsing failures
Status: CONFIRMED
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib (show other bugs)
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Future Release
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-05-19 06:35 UTC by Ian Jones
Modified: 2017-09-29 14:48 UTC (History)
7 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Test case (based on bug description) (10.38 KB, application/zip)
2017-05-19 11:03 UTC, Vincent Dondain [MSFT]
Details
My Solution>New to reproduce (11.00 KB, application/zip)
2017-05-19 12:54 UTC, Ian Jones
Details
Build Log 20170520 (376.96 KB, text/plain)
2017-05-20 00:08 UTC, Ian Jones
Details
Device Log 20170520 (11.74 KB, text/plain)
2017-05-20 00:13 UTC, Ian Jones
Details

Description Ian Jones 2017-05-19 06:35:49 UTC
Support, 

Had some datetime parsing occurring as part of the Json.Newton library, with a time format that's been ok for years now.
Did a release last week for app via Xamarin Studio and no problems on iOS or Droid devices.

Moved to Visual Studio for Mac, running latest 'stable' release of everything.
Following works fine on any/all Android simulators/devices, and iOS simulator, fails on all tested iOS devices (iPhone6, iPad Pro) :-

var dateText = "2017-May-19 00:00:00.00000";
var dateTimeFormat = "yyyy-MMM-dd HH:mm:ss.fffff";
var dateTimeStyles = System.Globalization.DateTimeStyles.RoundtripKind;
var culture = System.Globalization.CultureInfo.CurrentCulture;
// works.
DateTime dte = DateTime.Parse(dateText, culture, dateTimeStyles);
// fails.
dte = DateTime.ParseExact(dateText, dateTimeFormat, culture, dateTimeStyles);


Fails ALL attempts at simple/complex dateTimeFormat options.

Basic error output is :-

at System.DateTimeParse.ParseExact (System.String s, System.String format, System.Globalization.DateTimeFormatInfo dtfi, System.Globalization.DateTimeStyles style) [0x00023] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/globalization/datetimeparse.cs:57 
at System.DateTime.ParseExact (System.String s, System.String format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style) [0x0000b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/datetime.cs:1054 at myApp.Login+<doLoginAsync>d__24.MoveNext () [0x00443] in /myApp/Screens/Login.cs:475 

Thanks In Advance!
Comment 1 Vincent Dondain [MSFT] 2017-05-19 11:03:43 UTC
Created attachment 22304 [details]
Test case (based on bug description)
Comment 2 Vincent Dondain [MSFT] 2017-05-19 11:09:24 UTC
Hi,

I created a simple test case above with your code example.

I tried to run the code on an iPhone 7 (iOS 10.3) device with the following environment: https://gist.github.com/VincentDondain/bdc79e1cfdb63952a832d5ed59a7736b but I couldn't reproduce the issue.

Can you please include your full build logs, your test case (so we have the project options you used) and all version informations.

To get full build logs on Visual Studio for Mac just set the log verbosity to diagnostic in: Preferences > Projects > Build

The easiest way to get exact version information is to use the "Xamarin Studio" menu, "About Xamarin Studio" item, "Show Details" button and copy/paste the version informations (you can use the "Copy Information" button).
Comment 3 Ian Jones 2017-05-19 12:54:40 UTC
Created attachment 22310 [details]
My Solution>New to reproduce

Please note I just dumped sample code into FinishedLaunching().
Comment 4 Ian Jones 2017-05-19 12:55:36 UTC
=== Visual Studio Professional 2017 for Mac ===

Version 7.0 (build 3146)
Installation UUID: e530cf37-f41b-41fb-be92-699bd1dc92af
Runtime:
	Mono 5.0.0.100 (2017-02/9667aa6) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 500000100

=== NuGet ===

Version: 4.0.0.2323

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
SDK: /usr/local/share/dotnet/sdk/1.0.3/Sdks
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.0.0/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.5.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 8.3.2 (12175)
Build 8E2002

=== Xamarin.iOS ===

Version: 10.10.0.33 (Visual Studio Professional)
Hash: 3e5ac5ff
Branch: d15-2
Build date: 2017-05-05 18:11:38-0400

=== Xamarin.Android ===

Version: 7.3.0.13 (Visual Studio Professional)
Android SDK: /Users/ianjones/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		5.0 (API level 21)
		5.1 (API level 22)
		6.0 (API level 23)
		7.0 (API level 24)
		7.1 (API level 25)

SDK Tools Version: 25.2.5
SDK Platform Tools Version: 25.0.5
SDK Build Tools Version: 24.0.3

Java SDK: /usr
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Inspector ===

Version: 1.2.2
Hash: b71b035
Branch: d15-1
Build date: Fri, 21 Apr 2017 17:57:12 GMT

=== Xamarin.Mac ===

Version: 3.4.0.33 (Visual Studio Professional)

=== Build Information ===

Release ID: 700003146
Git revision: 7553fda2e327d15807298d444007896e5b975dba
Build date: 2017-05-09 12:12:36-04
Xamarin addins: c3d580752be79fc902422f1d55d1cdc2d8b98799
Build lane: monodevelop-lion-d15-2

=== Operating System ===

Mac OS X 10.12.5
Darwin 16.6.0 Darwin Kernel Version 16.6.0
    Fri Apr 14 16:21:16 PDT 2017
    root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

Redth's Addins 1.0.6
Comment 5 Ian Jones 2017-05-19 13:09:33 UTC
BTW - Your Bug56658 sample works!?
I've done a quick check of the info.plist and project settings and can't see any differences.

Please also try :-
var dateText = "9999-Dec-31 00:00:00.00000";
as it fails consistently even in your sample.
This is the actual use case that works under iOS simulator, but not on device.
It is also production example that has worked for last few years.

Thanks.
Comment 6 Ian Jones 2017-05-19 13:13:27 UTC
Here is production stack trace :-

System.DateTImeParse.ParseExact(System.String s, System.String format, System.Globalization.DateTimeFormatInfo dtfi, System.Globalization.DateTimeStyles style) in
/Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/globalization/datetimeparse.cs:57
System.DateTime.ParseExact(System.String s, System.String format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style) in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/datetime.cs:1054
 
Newtonsoft.Json.Converters.IsoDateTimeConverter.ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue, Newtonsoft.Json.JsonSerializer serializer) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(Newtonsoft.Json.JsonConverter converter, Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Object existingValue) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonConverter propertyConverter, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonReader reader, System.Object target) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(System.Object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.String id) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.JsonConvert.DeserializeObject(System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.JsonConvert.DeserializeObject[T](System.String value, Newtonsoft.Json.JsonSerializerSettings settings) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
Newtonsoft.Json.JsonConvert.DeserializeObject[T](System.String value) in <9b6398b0b3ae4afdb586fd62eda2ead4>:0
LifeCycle.Mobile.ExtensionMethods.FromJSONString[T](System.String jsonString, T defaultT, Newtonsoft.Json.JsonSerializerSettings settings) in <54352cd52784458faaa2af25229896f4>:0
LifeCycle.Mobile.ExtensionMethods.FromJSONString[T](System.String jsonString, Newtonsoft.Json.JsonSerializerSettings settings) in <54352cd52784458faaa2af25229896f4>:0
iPadFieldApp.Login+d__24.MoveNext() in /Users/ianjones/Documents/Projects/Xamarin/SMTS/FieldAppTFS/FieldApp/SMTS.FieldApp.iOS/Screens/Login.cs:518
Comment 7 Vincent Dondain [MSFT] 2017-05-19 13:39:33 UTC
So we have the same environment and now 2 samples.

I just tried you sample and it works for me on my iPhone 7 (iOS 10.3), I also tried to change my sample to: var dateText = "9999-Dec-31 00:00:00.00000"; and it worked.

I wonder if this could be a regression on some specific devices.

Can you detail the devices you have?

@gouri might I use your help here to try to reproduce this? (:
Comment 8 Vincent Dondain [MSFT] 2017-05-19 16:45:20 UTC
@Ian Can you add `Console.WriteLine (culture);` so we know what the devices are using?

Also please provide a full build log (diagnostic). On VSfM: Preferences > Projects > Build
Comment 9 Vincent Dondain [MSFT] 2017-05-19 17:19:42 UTC
Also what is the exception message for the parsing error? You only provided the stack trace (:
Comment 10 Ian Jones 2017-05-20 00:05:04 UTC
Vincent,
Devices are :-
iPad Pro 12" 128Gb running iOS 10.3.1
iPhone 6+ 64Gb iOS 10.3.1
Culture on both is 'en-AU'

String was not recognized as a valid DateTime.
mscorlib
  at System.DateTimeParse.ParseExact (System.String s, System.String format, System.Globalization.DateTimeFormatInfo dtfi, System.Globalization.DateTimeStyles style) [0x00023] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/globalization/datetimeparse.cs:57 
  at System.DateTime.ParseExact (System.String s, System.String format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style) [0x0000b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.33/src/mono/mcs/class/referencesource/mscorlib/system/datetime.cs:1054 
  at Test01.ViewController.ViewDidLoad () [0x00044] in /Users/ianjones/Documents/Projects/Test01/Test01/ViewController.cs:29 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/4691/3e5ac5ff/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/4691/3e5ac5ff/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
  at Test01.Application.Main (System.String[] args) [0x00001] in /Users/ianjones/Documents/Projects/Test01/Test01/Main.cs:12
Comment 11 Ian Jones 2017-05-20 00:08:03 UTC
Created attachment 22324 [details]
Build Log 20170520

and the build log.
Comment 12 Ian Jones 2017-05-20 00:13:35 UTC
Created attachment 22325 [details]
Device Log 20170520

and the device log.
Comment 13 Ian Jones 2017-05-20 05:32:58 UTC
Stop press - looks like the culture!?

Using my default "en-AU" it fails.
Forcing "en-US" works :-
  culture = new System.Globalization.CultureInfo("en-US", true);
Not sure what's going on internally for that to break things.

Added this to the client app, and all works.
Still keen to understand why, and why you think it only broke recently.
Especially given that the ParseExact() takes an exact format for translation?

Also, mildly insulted someone thought to break Aussie culture :)

Thanks.
Comment 14 Vincent Dondain [MSFT] 2017-05-22 11:10:52 UTC
Indeed it's the culture (:

This happens because of the MMM custom format specifier.

See: https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx#MMM_Specifier

"The "MMM" custom format specifier represents the abbreviated name of the month. The localized abbreviated name of the month is retrieved from the DateTimeFormatInfo.AbbreviatedMonthNames property of the current or specified culture."

You can check the month for the current culture like this:

var culture = CultureInfo.CurrentCulture;
var monthNames = culture.DateTimeFormat.AbbreviatedMonthNames;
foreach (var month in monthNames)
	Console.WriteLine (month);

For some reason, all month (except May) have a "." at the end.

So your "9999-Dec-31 00:00:00.00000" examples should be "9999-Dec.-31 00:00:00.00000" with "Dec." for a culture set to "Aussie".

This seems like a BCL bug to me. The results for a NETStandard project do not contain the "." and are similar to en-US.
Comment 15 Ian Jones 2017-05-26 07:09:36 UTC
Vincent,
Thanks for your help and detailed responses!
In this instance I'm happy to enforce en-US as a 'permanent' workaround.
Regards,
Ian
Comment 16 Marek Safar 2017-09-29 14:48:01 UTC
Simple repro

            var dateText = "2017-Apr-19 00:00:00.00000";
            var dateTimeFormat = "yyyy-MMM-dd HH:mm:ss.fffff";
            var dateTimeStyles = System.Globalization.DateTimeStyles.RoundtripKind;
            var culture = new System.Globalization.CultureInfo("en-AU");
            var dte = DateTime.ParseExact(dateText, dateTimeFormat, culture, dateTimeStyles);

Note You need to log in before you can comment on or make changes to this bug.