Bug 22417 - DateTime.Parse does not correctly recognize the date with correct format
Summary: DateTime.Parse does not correctly recognize the date with correct format
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib ()
Version: 3.8.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: marcos.henrich
URL:
Depends on:
Blocks:
 
Reported: 2014-08-27 14:10 UTC by Ahmet Alp Balkan
Modified: 2015-02-04 09:34 UTC (History)
6 users (show)

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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Ahmet Alp Balkan 2014-08-27 14:10:05 UTC
The following code parsing ISO8601 date strings into DateTime objects is not working on Mono but works on Microsoft .NET implementation on Windows.

The famou Newtonsoft.Json library uses the following date format, culture and datetimestyles to parse ISO8601 string into DateTime:

public static void Main (string[] args)
{
    string Iso8601Format = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
    string date = "2014-08-25T01:20:23.60191161Z";
    DateTime dt = DateTime.Parse(date, CultureInfo.CurrentCulture, DateTimeStyles.RoundtripKind);
    Console.WriteLine(dt);
}


This program fails with the following error on Mono:

System.FormatException: String was not recognized as a valid DateTime.
at System.DateTime.Parse (System.String s, IFormatProvider provider, DateTimeStyles styles) [0x00027] in /Volumes/build-root-ramdisk/mono-3.8.0/mcs/class/corlib/System/DateTime.cs:845
  at Demo.MainClass.Main (System.String[] args) [0x0000c] in /Users/alp/workspace/Demo/Demo/Program.cs:24 


Mono information:
=================
Mono JIT compiler version 3.8.0 ((no/62a857e Wed Aug 13 00:46:20 EDT 2014)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           normal
	SIGSEGV:       altstack
	Notification:  kqueue
	Architecture:  x86
	Disabled:      none
	Misc:          softdebug 
	LLVM:          yes(3.4svn-mono-(no/e656cac)
	GC:            sgen

===
The bug I opened on Newtonsoft.Json side: https://github.com/JamesNK/Newtonsoft.Json/issues/355
Comment 1 Ahmet Alp Balkan 2014-08-27 14:50:09 UTC
Forgot to use the format string in the example above, changing example to ParseExact:

string iso8601Format = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
string date = "2014-08-25T01:20:23.60191161Z";
DateTime dt = DateTime.ParseExact (date, iso8601Format, CultureInfo.CurrentCulture, DateTimeStyles.RoundtripKind);

This throws:

System.FormatException: Invalid format string   
at System.DateTime.ParseExact (System.String s, System.String[] formats, IFormatProvider provider, DateTimeStyles style) [0x0005c] in /Volumes/build-root-ramdisk/mono-3.8.0/mcs/class/corlib/System/DateTime.cs:1800    
at System.DateTime.ParseExact (System.String s, System.String format, IFormatProvider provider, DateTimeStyles style) [0x0001c] in /Volumes/build-root-ramdisk/mono-3.8.0/mcs/class/corlib/System/DateTime.cs:1780    
...
Comment 2 Ahmet Alp Balkan 2014-08-27 15:23:42 UTC
Here's a simpler example that's not working on Mono but works on Microsoft .NET:

var dt = DateTime.Parse ("2014-08-25T01:20:23.60191161Z", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
Comment 3 David Hathaway 2014-08-28 16:03:04 UTC
To add to this item, I've also found that the following format returns the same exception on Mono (it works fine on Windows).  Repro attached.

			string date = "20141212";
			DateTimeOffset dtOffset;

			try {
				dtOffset = DateTimeOffset.ParseExact(date, "yyyyMMdd", CultureInfo.CurrentCulture);
				Console.WriteLine (dtOffset.ToString());
			}
 			catch(Exception ex) {
				Console.WriteLine (ex.ToString());
			}

However, the following works

			date ="2014-08-08";

			try {
				dtOffset = DateTimeOffset.ParseExact(date, "yyyy-MM-dd", CultureInfo.CurrentCulture);
				Console.WriteLine (dtOffset.ToString());
			}
			catch(Exception ex) {
				Console.WriteLine (ex.ToString());
			}
Comment 4 David Hathaway 2014-08-28 16:05:04 UTC
Couldn't add attachment, but here is the complete repro.  Just run this as a Console app both on Mac and Windows, and you'll see that the first portion fails on Mac, but both options run successfully on Windows.

using System;
using System.Globalization;

namespace DateTimeParse
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string date = "20141212";
			DateTimeOffset dtOffset;

			try {
				dtOffset = DateTimeOffset.ParseExact(date, "yyyyMMdd", CultureInfo.CurrentCulture);
				Console.WriteLine (dtOffset.ToString());
			}
 			catch(Exception ex) {
				Console.WriteLine (ex.ToString());
			}

			//Reformat the string to input it in the yyyy-MM-dd format
			date = int.Parse(date).ToString("####-0#-0#"); //"2014-08-08";

			try {
				dtOffset = DateTimeOffset.ParseExact(date, "yyyy-MM-dd", CultureInfo.CurrentCulture);
				Console.WriteLine (dtOffset.ToString());
			}
			catch(Exception ex) {
				Console.WriteLine (ex.ToString());
			}

			Console.WriteLine ("Press any key to exit");
			Console.Read ();
		}
	}
}
Comment 5 marcos.henrich 2014-09-03 06:45:55 UTC
Hi Ahmet, David.

Thank you for the detailed bug report.

.NET is capable of parsing ISO8601 format with a unlimited number of fractional digits. Whereas Mono was only parsing a maximum of 7 digits and in your example you were parsing 8 fractional digits.

The pull request for this issue can be found in the link below.
https://github.com/mono/mono/pull/1253

David your issue is fixed in mono master.
Comment 6 marcos.henrich 2014-09-08 11:51:09 UTC
Fixed in master 4bd9820eaa1a90ad3437f7ab8df28ce20d3f02c9.
https://github.com/mono/mono/commit/4bd9820eaa1a90ad3437f7ab8df28ce20d3f02c9
Comment 7 Sunil Kumar 2014-11-27 09:59:22 UTC
I have checked this issue and now this issue works fine.

I have run the code mentioned in comment 4 with mono 3.8 and I observed that first portion fails and only second portion runs successfully.

But with Mono 3.12.0.46 both portions of the code runs successfully without any exception/error.

Screencast: http://www.screencast.com/t/m0UmWnvz98

Hence, I am closing this issue.

Environment info:
=== Xamarin Studio ===

Version 5.7 (build 596)
Installation UUID: 561c7a69-0a91-4bae-ad7c-f0c79d594337
Runtime:
	Mono 3.12.0 ((detached/b75fa2b)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 312000046

=== Apple Developer Tools ===

Xcode 5.1.1 (5085)
Build 5B1008

=== Xamarin.iOS ===

Version: 8.6.0.5 (Trial Edition)
Hash: 880cc21
Branch: 
Build date: 2014-11-25 12:12:17-0500

=== Xamarin.Android ===

Version: 5.0.0.0 (Trial Edition)
Android SDK: /Users/tajinder/Desktop/android-sdk-macosx
	Supported Android versions:
		2.3    (API level 10)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
Java SDK: /usr
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Xamarin.Mac ===

Version: 1.11.1.201 (Indie Edition)

=== Build Information ===

Release ID: 507000596
Git revision: d996e9ba6874a0d64241e43e5e6b06322ce29c84
Build date: 2014-11-25 17:17:54-05
Xamarin addins: 8ca19707b41536a391f53364ee4ff9272711feb0

=== Operating System ===

Mac OS X 10.8.4
Darwin Tajinders-iMac.local 12.4.2 Darwin Kernel Version 12.4.2
    Mon Jun 17 18:00:12 PDT 2013
    root:xnu-2050.45.8~1/RELEASE_X86_64 x86_64
Comment 8 Alexander Schmidt 2015-02-04 09:34:23 UTC
I have to add that this problem is urgent when it comes to XML serialization. If you try to send DateTimeOffset over services, you need to implement something like this:

[XmlIgnore]
public DateTimeOffset MyTime { get; set; }

[XmlElement("MyTime")]
public string MyTimeAsString
{
    get { return MyTime.ToString(); }
    set { MyTime = DateTimeOffset.Parse(value); }
}

I know that this approach lacks exception handling and cultures but this works fine under .NET which makes it difficult to see the error.

Alex