From 80a0b584ee8d803392ab9362ee05a154370ade7d Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Sun, 3 Sep 2017 03:54:57 -0600 Subject: [PATCH] Fix issue 17801: DateTime.fromISOExtString no longer works with const strings. The from*String functions in std.datetime did not have tests to make sure that they worked with various character types or various levels of constness, and some optimizations that were done to the from*String functions on DateTime for 2.076 broke them for const strings. So, this adds tests for all character types and levels of constness to each of the from*String function in std.datetime, and fixes the functionality for DateTime that then doesn't pass the tests. --- std/datetime/date.d | 102 +++++++++++++++++++++++++++++++++++++++-- std/datetime/systime.d | 45 ++++++++++++++++++ 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index c3ed199c6aa..fbe986a1b9f 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -3106,7 +3106,7 @@ public: import std.format : format; import std.string : strip; - immutable str = strip(isoString); + auto str = strip(isoString); enforce(str.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString))); auto t = str.countUntil('T'); @@ -3172,6 +3172,18 @@ public: assert(DateTime.fromISOString(" 19990706T123033 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(DateTime.fromISOString(to!S("20121221T141516")) == DateTime(2012, 12, 21, 14, 15, 16)); + } + } + /++ Creates a $(LREF DateTime) from a string with the format @@ -3194,7 +3206,7 @@ public: import std.format : format; import std.string : strip; - immutable str = strip(isoExtString); + auto str = strip(isoExtString); enforce(str.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); auto t = str.countUntil('T'); @@ -3259,6 +3271,18 @@ public: assert(DateTime.fromISOExtString(" 1999-07-06T12:30:33 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(DateTime.fromISOExtString(to!S("2012-12-21T14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16)); + } + } + /++ Creates a $(LREF DateTime) from a string with the format @@ -3281,7 +3305,7 @@ public: import std.format : format; import std.string : strip; - immutable str = strip(simpleString); + auto str = strip(simpleString); enforce(str.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString))); auto t = str.countUntil(' '); @@ -3350,6 +3374,18 @@ public: DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(DateTime.fromSimpleString(to!S("2012-Dec-21 14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16)); + } + } + /++ Returns the $(LREF DateTime) farthest in the past which is representable @@ -7467,6 +7503,18 @@ public: assert(Date.fromISOString(" 19990706 ") == Date(1999, 7, 6)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(Date.fromISOString(to!S("20121221")) == Date(2012, 12, 21)); + } + } + /++ Creates a $(LREF Date) from a string with the format YYYY-MM-DD. @@ -7596,6 +7644,18 @@ public: assert(Date.fromISOExtString(" 1999-07-06 ") == Date(1999, 7, 6)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(Date.fromISOExtString(to!S("2012-12-21")) == Date(2012, 12, 21)); + } + } + /++ Creates a $(LREF Date) from a string with the format YYYY-Mon-DD. @@ -7722,6 +7782,18 @@ public: assert(Date.fromSimpleString(" 1999-Jul-06 ") == Date(1999, 7, 6)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(Date.fromSimpleString(to!S("2012-Dec-21")) == Date(2012, 12, 21)); + } + } + /++ Returns the $(LREF Date) farthest in the past which is representable by @@ -8986,6 +9058,18 @@ public: assert(TimeOfDay.fromISOString(" 011217 ") == TimeOfDay(1, 12, 17)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(TimeOfDay.fromISOString(to!S("141516")) == TimeOfDay(14, 15, 16)); + } + } + /++ Creates a $(LREF TimeOfDay) from a string with the format HH:MM:SS. @@ -9101,6 +9185,18 @@ public: assert(TimeOfDay.fromISOExtString(" 01:12:17 ") == TimeOfDay(1, 12, 17)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + assert(TimeOfDay.fromISOExtString(to!S("14:15:16")) == TimeOfDay(14, 15, 16)); + } + } + /++ Returns midnight. diff --git a/std/datetime/systime.d b/std/datetime/systime.d index a4fc5b3201a..e0df970beda 100644 --- a/std/datetime/systime.d +++ b/std/datetime/systime.d @@ -8480,6 +8480,21 @@ public: test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + { + assert(SysTime.fromISOString(to!S("20121221T141516Z")) == + SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); + } + } + } + /++ Creates a $(LREF SysTime) from a string with the format @@ -8706,6 +8721,21 @@ public: test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + { + assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == + SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); + } + } + } + /++ Creates a $(LREF SysTime) from a string with the format @@ -8935,6 +8965,21 @@ public: test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); } + // bug# 17801 + @safe unittest + { + import std.conv : to; + import std.meta : AliasSeq; + foreach (C; AliasSeq!(char, wchar, dchar)) + { + foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) + { + assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == + SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); + } + } + } + /++ Returns the $(LREF SysTime) farthest in the past which is representable