DateTime decimal separator: Added ',' version to regex and docs, added unit tests

Change-Id: I04a566ee1ac39074f0b410e5aec5cff8c8b2ae02
Reviewed-on: https://dart-review.googlesource.com/c/88904
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2677614..4056706 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,13 @@
 
 ### Core library changes
 
+#### `dart:core`
+
+*   Made `DateTime.parse()` also recognize `,` as a valid decimal separator 
+    when parsing from a string. (Issue [35576][])
+
+[35576]: https://github.com/dart-lang/sdk/issues/35576
+
 ### Dart VM
 
 ### Tool Changes
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 1f46d11..b24c0ea 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -237,10 +237,10 @@
    *   The time part is a two digit hour,
    *   then optionally a two digit minutes value,
    *   then optionally a two digit seconds value, and
-   *   then optionally a '.' followed by a one-to-six digit second fraction.
+   *   then optionally a '.' or ',' followed by a one-to-six digit second fraction.
    *   The minutes and seconds may be separated from the previous parts by a
    *   ':'.
-   *   Examples: "12", "12:30:24.124", "123010.50".
+   *   Examples: "12", "12:30:24.124", "12:30:24,124", "123010.50".
    * * An optional time-zone offset part,
    *   possibly separated from the previous by a space.
    *   The time zone is either 'z' or 'Z', or it is a signed two digit hour
@@ -261,6 +261,7 @@
    *
    * * `"2012-02-27 13:27:00"`
    * * `"2012-02-27 13:27:00.123456z"`
+   * * `"2012-02-27 13:27:00,123456z"`
    * * `"20120227 13:27:00"`
    * * `"20120227T132700"`
    * * `"20120227"`
@@ -852,7 +853,7 @@
    * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
    * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
    * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
-   * micros_opt ::= <empty> | '.' digit{1,6}
+   * micros_opt ::= <empty> | ('.' | ',') digit{1,6}
    * timezone_opt ::= <empty> | space_opt timezone
    * space_opt :: ' ' | <empty>
    * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
@@ -860,6 +861,6 @@
    */
   static final RegExp _parseFormat = new RegExp(
       r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
-      r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d{1,6}))?)?)?' // Time part.
+      r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,6}))?)?)?' // Time part.
       r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
 }
diff --git a/tests/corelib_2/date_time_parse_test.dart b/tests/corelib_2/date_time_parse_test.dart
index 74cc78f..6b3d58d 100644
--- a/tests/corelib_2/date_time_parse_test.dart
+++ b/tests/corelib_2/date_time_parse_test.dart
@@ -18,9 +18,13 @@
   if (supportsMicroseconds) {
     check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
         "2012-02-27 13:27:00.123456z");
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+        "2012-02-27 13:27:00,123456z");
   } else {
     check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
         "2012-02-27 13:27:00.123z");
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+        "2012-02-27 13:27:00,123z");
   }
   check(new DateTime(2012, 02, 27, 13, 27), "20120227 13:27:00");
   check(new DateTime(2012, 02, 27, 13, 27), "20120227T132700");