Cherry-picked `TimeAndDateTest` from f0b998af5ae3 jv
authorJan Vrany <jan.vrany@labware.com>
Tue, 08 Jun 2021 22:27:00 +0100
branchjv
changeset 2596 29692e2d213f
parent 2595 0ae7d724b885
child 2597 9496e0bdef34
Cherry-picked `TimeAndDateTest` from f0b998af5ae3 cherry-picked RegressionTests__TimeAndDateTest.st from f0b998af5ae3: * df3c6ccdb0e7: #REFACTORING by mawalch, mawalch * 6deb0e9fa0d2: #QUALITY by cg, Claus Gittinger <cg@exept.de> * cc644916d874: #QUALITY by cg, Claus Gittinger <cg@exept.de> * ac82d7231d95: #QUALITY by cg, Claus Gittinger <cg@exept.de> * 8e0e4fbf523d: #QUALITY by cg, Claus Gittinger <cg@exept.de> * 0d55f748fc8b: Refactored `MakefileTests`, Jan Vrany <jan.vrany@fit.cvut.cz> * 5cfaf842bed0: #REFACTORING by stefan, Stefan Vogel <sv@exept.de> * c7cb74c4ed7b: #QUALITY by cg, Claus Gittinger <cg@exept.de> * c4bfc248aace: #QUALITY by exept, Claus Gittinger <cg@exept.de>
RegressionTests__TimeAndDateTest.st
--- a/RegressionTests__TimeAndDateTest.st	Thu Mar 18 23:32:27 2021 +0000
+++ b/RegressionTests__TimeAndDateTest.st	Tue Jun 08 22:27:00 2021 +0100
@@ -12,119 +12,6 @@
 
 !TimeAndDateTest methodsFor:'Testing'!
 
-test_01_ReadingTimes
-
-     self assert:(Time readFrom:'0:00'    ) = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'2:00'    ) = (Time hour:2 minute:0 second:0).
-     self assert:(Time readFrom:'12:00'   ) = (Time hour:12 minute:0 second:0).
-     self assert:(Time readFrom:'14:00'   ) = (Time hour:14 minute:0 second:0).
-     self assert:(Time readFrom:'23:00'   ) = (Time hour:23 minute:0 second:0).
-     self assert:(Time readFrom:'24:00'   ) = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'2:30 am' ) = (Time hour:2 minute:30 second:0).
-     self assert:(Time readFrom:'2:30 pm' ) = (Time hour:14 minute:30 second:0).
-     self assert:(Time readFrom:'14'      ) = (Time hour:14 minute:0 second:0).
-     self assert:(Time readFrom:'2 am'    ) = (Time hour:2 minute:0 second:0).
-     self assert:(Time readFrom:'2 pm'    ) = (Time hour:14 minute:0 second:0).
-     self assert:(Time readFrom:'12:05 pm') = (Time hour:12 minute:5 second:0).
-     self assert:(Time readFrom:'12:06 am') = (Time hour:0 minute:6 second:0).
-
-     self assert:(Time readFrom:'18:22:00') = (Time hour:18 minute:22 second:0).
-     self assert:(Time readFrom:'14:00:11') = (Time hour:14 minute:0 second:11).
-     self assert:(Time readFrom:'7:00:11' ) = (Time hour:7 minute:0 second:11).
-     self assert:(Time readFrom:'24:00:00') = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'0:00:00' ) = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'12:00:00') = (Time hour:12 minute:0 second:0).
-     self assert:(Time readFrom:'0:00:00' ) = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'6:22:00 pm' ) = (Time hour:18 minute:22 second:0).
-     self assert:(Time readFrom:'2:00:11 pm' ) = (Time hour:14 minute:0 second:11).
-     self assert:(Time readFrom:'7:00:11 am' ) = (Time hour:7 minute:0 second:11).
-     self assert:(Time readFrom:'12:00:00 am') = (Time hour:0 minute:0 second:0).
-     self assert:(Time readFrom:'0:00:00 am' ) = (Time hour:0 minute:0 second:0).
-     self should:[ Time readFrom:'24:00:00 am' ] raise:TimeConversionError.
-     self assert:(Time readFrom:'12:00:00 pm') = (Time hour:12 minute:0 second:0).
-     self assert:(Time readFrom:'0:00:00 pm' onError:'invalid') = 'invalid'.
-     self should:[ Time readFrom:'24:00:00 pm' ] raise:TimeConversionError.
-
-    "
-     self new test_01_Reading
-    "
-!
-
-test_02_ReadingDates
-
-     self assert:(Date
-		    readFrom:'2-may-2010'
-		    printFormat:'%d-%shortMonthName-%y'
-		    language:'en'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-    {
-	{   '3-jan-2012'   .   (Date newDay:3 month:1 year:2012)    } .
-	{   '15-feb-2012'   .   (Date newDay:15 month:2 year:2012)  } .
-	{   '06-mar-2011'   .   (Date newDay:6 month:3 year:2011)   } .
-	{   '19-apr-2013'   .   (Date newDay:19 month:4 year:2013)  } .
-	{   '21-may-2015'   .   (Date newDay:21 month:5 year:2015)  } .
-	{   '21-jun-2015'   .   (Date newDay:21 month:6 year:2015)  } .
-	{   '21-jul-2015'   .   (Date newDay:21 month:7 year:2015)  } .
-	{   '21-aug-2015'   .   (Date newDay:21 month:8 year:2015)  } .
-	{   '21-sep-2015'   .   (Date newDay:21 month:9 year:2015)  } .
-	{   '21-oct-2015'   .   (Date newDay:21 month:10 year:2015)  } .
-	{   '21-nov-2015'   .   (Date newDay:21 month:11 year:2015)  } .
-	{   '21-dec-2015'   .   (Date newDay:21 month:12 year:2015)  } .
-    } do:[:eachTestPair |
-	 self assert:(Date
-			readFrom:(eachTestPair first)
-			printFormat:'%d-%shortMonthName-%y'
-			language:'en'
-			onError:[self error]
-		      ) = (eachTestPair second).
-    ].
-
-     self assert:(Date
-		    readFrom:'2-may-2010'
-		    printFormat:'%d-%monthName-%y'
-		    language:'en'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-     self assert:(Date
-		    readFrom:'2-may-2010'
-		    printFormat:'%d-%(shortMonthName)-%y'
-		    language:'en'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-     self assert:(Date
-		    readFrom:'2-may-2010'
-		    printFormat:'%d-%(monthName)-%y'
-		    language:'en'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-     self assert:(Date
-		    readFrom:'2-5-2010'
-		    printFormat:'%d-%m-%y'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-     self assert:(Date
-		    readFrom:'5/2/2010'
-		    printFormat:'%m/%d/%y'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-     self assert:(Date
-		    readFrom:'2010-5-2'
-		    printFormat:'%y-%m-%d'
-		    onError:[self error]
-		  ) = (Date newDay:2 month:5 year:2010).
-
-    "
-     self new test_02_ReadingDates
-    "
-!
-
 test_03_calenderWeek
     self assert:(Date newDay:5 month:11 year:2012) weekInYear == 45.
     self assert:(Date newDay:11 month:11 year:2012) weekInYear == 45.
@@ -212,6 +99,657 @@
     "
 !
 
+test_10_readingISO8601_time
+    "/ the old ISO8601Builder tests moved to here
+
+    | ts reader |
+
+    reader := Timestamp::TimestampISO8601Builder.
+
+    ts := UtcTimestamp  year: 2005 month: 6 day: 15 hour: 17 minute: 37 second: 0 millisecond: 0.
+    self assert: ts = (reader read: '2005-06-15 17:37' withClass:UtcTimestamp).
+    self assert: ts = (reader read: '20050615T1737' withClass:UtcTimestamp).
+    self assert: ts = (reader read: '05-0615T17:3700' withClass:UtcTimestamp).
+
+    ts := UtcTimestamp  year: 2005 month: 6 day: 15 hour: 17 minute: 37 second: 0 millisecond: 30.
+    self assert: ts = (reader read: '05-0615T17:3700.03' withClass:UtcTimestamp).
+    self assert: ts = (reader read: '2005-06-15T17:37:00.030' withClass:UtcTimestamp).
+
+    ts := UtcTimestamp  year: 2005 month: 6 day: 15 hour: 17 minute: 37 second: 0 microsecond:300.
+    self assert: ts = (reader read: '05-0615T17:3700.0003' withClass:UtcTimestamp).
+    self assert: ts = (reader read: '2005-06-15T17:37:00.0003-00:00' withClass:UtcTimestamp).
+
+    "
+     self new test_10_readingISO8601_time
+    "
+!
+
+test_12_dateQueries
+    |d1 d2 d3|
+
+    d1 := Date newDay:1 month:2 year:1940.
+    d2 := Date newDay:1 month:2 year:1941.
+    self assert:(d2 - d1) = 366.
+
+    d1 := Date newDay:1 month:2 year:1840.
+    d2 := Date newDay:1 month:2 year:1841.
+    self assert:(d2 - d1) = 366.
+    self assert:(d1 addDays:366) = d2.
+
+    Date leapYear:1540.
+    d1 := Date newDay:1 month:2 year:1540.
+    d2 := Date newDay:1 month:2 year:1541.
+    self assert:(d2 - d1) = 366.
+
+    d1 := Date newDay:1 year:1901.
+    self assert:(d1 day = 1).
+    self assert:(d1 month = 1).
+    self assert:(d1 year = 1901).
+
+    "/ 1900 was NOT a leap year
+    self assert:(Date leapYear:1900) not.
+    "/ 2000 was a leap year
+    self assert:(Date leapYear:2000).
+
+    d2 := d1 subtractDays:365.
+    self assert:(d2 day = 1).
+    self assert:(d2 month = 1).
+    self assert:(d2 year = 1900).
+
+    d3 := d2 subtractDays:365.
+    self assert:(d3 day = 1).
+    self assert:(d3 month = 1).
+    self assert:(d3 year = 1899).
+
+    d1 := Date newDay:1 month:2 year:2540.
+    d2 := Date newDay:1 month:2 year:2541.
+    self assert:(d2 - d1) = 366.
+
+
+    "
+     self new test_12_dateQueries
+    "
+!
+
+test_13_timestampQueries
+    |d1 d2 local utc|
+
+    d1 := UtcTimestamp year:2000 month:1 day:1.
+    d2 := UtcTimestamp year:2001 month:1 day:1.
+    self assert:(d2 - d1) days = 366.
+
+    d1 := UtcTimestamp year:1940 month:1 day:2.
+    d2 := UtcTimestamp year:1941 month:1 day:2.
+    self assert:d1 asDate year = 1940.
+    self assert:d2 asDate year = 1941.
+    self assert:d1 asDate month = 1.
+    self assert:d2 asDate month = 1.
+    self assert:d1 asDate day = 2.
+    self assert:d2 asDate day = 2.
+
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    d1 := UtcTimestamp year:1840 month:1 day:1.
+    d2 := UtcTimestamp year:1841 month:1 day:1.
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    self assert:(d1 addDays:366) = d2.
+
+    d1 := UtcTimestamp year:1540 month:1 day:1.
+    d2 := UtcTimestamp year:1541 month:1 day:1.
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    d1 := UtcTimestamp year:2038 month:1 day:1.
+    d2 := UtcTimestamp year:2039 month:1 day:1.
+    self assert:d1 asDate isLeapYear not.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 365.
+
+    d1 := UtcTimestamp year:2540 month:1 day:1.
+    d2 := UtcTimestamp year:2541 month:1 day:1.
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    d1 := UtcTimestamp year:3540 month:1 day:1.
+    d2 := UtcTimestamp year:3541 month:1 day:1.
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    d1 := UtcTimestamp year:1969 month:1 day:1.
+    d2 := UtcTimestamp year:1970 month:1 day:1.
+    self assert:d1 asDate isLeapYear not.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 365.
+
+    d1 := UtcTimestamp year:1600 month:1 day:1.
+    d2 := UtcTimestamp year:1601 month:1 day:1.
+    self assert:d1 asDate isLeapYear.
+    self assert:d2 asDate isLeapYear not.
+    self assert:(d2 - d1) days = 366.
+
+    "/ local time vs. utc time
+    local := Timestamp year:1940 month:1 day:1.
+    utc := UtcTimestamp year:1940 month:1 day:1.
+    self assert:(local asUtcTimestamp - utc asUtcTimestamp) asSeconds = local utcOffset.
+
+    "/ tz time vs. utc time
+    utc := Timestamp readFrom:'20000102T123000Z'.
+    local := Timestamp readFrom:'20000102T123000+02'.
+    self assert:(utc - local) asSeconds = 7200.
+
+    "/ tz time vs. utc time
+    utc := UtcTimestamp readFrom:'20000102T123000Z'.
+    local := UtcTimestamp readFrom:'20000102T123000-02'.
+    self assert:(utc - local) asSeconds = -7200.
+
+    "
+     self new test_13_timestampQueries
+    "
+
+    "Modified: / 27-07-2018 / 09:59:25 / Stefan Vogel"
+!
+
+test_14_arithmetic
+    |t1 t2 t3 s|
+
+    t1 := UtcTimestamp newDay:1 month:1 year:2000.
+    t2 := t1 addDays:1.
+    self assert:(t2 - t1) days = 1.
+
+    t2 := t1 addHours:1.
+    self assert:(t2 - t1) hours = 1.
+
+    t2 := t1 addSeconds:1.
+    self assert:(t2 - t1) seconds = 1.
+
+    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
+    t2 := t1 addDays:1.
+    self assert:(t2 printString = '2000-01-03 13:30:45Z').
+
+    t1 := Timestamp readFrom:'20000102T133045+01'.
+    t2 := t1 addDays:1.
+    self assert:(t2 printString = '2000-01-03 13:30:45+01').
+
+    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
+    t2 := Timestamp readFrom:'20000102T133045Z'.
+    self assert:(t1 = t2).
+
+    t2 := Timestamp readFrom:'20000102T143045+01'.
+    self assert:(t1 = t2).
+
+    t2 := Timestamp readFrom:'20000102T123045-01'.
+    self assert:(t1 = t2).
+
+    t2 := Timestamp readFrom:'20000102T123045'.     "/ a local one
+    s := t2 storeString.
+    t3 := Timestamp readFrom:s.
+
+    self assert:(t2 = t3).
+
+    t1 := TZTimestamp readFrom:'20000102T133045Z'.
+    self assert:(t1 printString = '2000-01-02 13:30:45+00').
+    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
+    self assert:(t1 printString = '2000-01-02 13:30:45Z').
+
+    "
+     self new test_14_arithmetic
+    "
+!
+
+test_15_misc
+    #( 1700  1800  1900  2100  2200 ) do:[:y |
+	self assert:(Date leapYear:y) not
+    ].
+    #( 1600  2000 2400 ) do:[:y |
+	self assert:(Date leapYear:y)
+    ].
+
+    "
+     self new test_15_misc
+    "
+!
+
+test_18_moreTimestampArithmetic
+    |t1 t2|
+
+    t1 := Timestamp year:2000 month:1 day:1.
+    t2 := t1 addMilliseconds:1.
+    self assert:t1 seconds = 0.
+    self assert:t2 seconds = 0.
+    self assert:t1 exactSeconds = 0.
+    self assert:t2 exactSeconds = 0.001.
+    self assert:t1 milliseconds = 0.
+    self assert:t2 milliseconds = 1.
+    self assert:t1 microseconds = 0.
+    self assert:t2 microseconds = 1000.
+    self assert:t1 nanoseconds = 0.
+    self assert:t2 nanoseconds = 1000000.
+    self assert:t1 picoseconds = 0.
+    self assert:t2 picoseconds = 1000000000.
+
+    self assert:(t2 - t1) milliseconds = 1.
+    self assert:(t2 - t1) microseconds = 1000.
+    self assert:(t2 - t1) nanoseconds = 1000000.
+    self assert:(t2 - t1) picoseconds = 1000000000.
+
+    "
+     self new test_18_moreArithmetic
+    "
+!
+
+test_19_comparing
+    |t1 t2|
+
+    t1 := Time now.
+    t2 := t1 addMilliseconds:1.
+
+    self assert:t2 > t1.
+    self assert:t2 >= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 <= t1) not.
+    self assert:(t2 < t1) not.
+
+    t1 := Time now.
+    t2 := t1 subtractMilliseconds:1.
+
+    self assert:t2 < t1.
+    self assert:t2 <= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 >= t1) not.
+    self assert:(t2 > t1) not.
+
+    t1 := Time now.
+    t2 := t1 + 1 milliseconds.
+    self assert:t2 = (t1 addMilliseconds:1).
+
+    t2 := t1 - 1 milliseconds.
+    self assert:t2 = (t1 addMilliseconds:-1).
+    self assert:t2 = (t1 subtractMilliseconds:1).
+
+    "
+     self new test_19_comparing
+    "
+!
+
+test_20_comparing
+    |t1 t2|
+
+    t1 := Timestamp now.
+    t2 := t1 addMilliseconds:1.
+
+    self assert:t2 > t1.
+    self assert:t2 >= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 <= t1) not.
+    self assert:(t2 < t1) not.
+
+    t1 := Timestamp now.
+    t2 := t1 subtractMilliseconds:1.
+
+    self assert:t2 < t1.
+    self assert:t2 <= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 >= t1) not.
+    self assert:(t2 > t1) not.
+
+    t1 := Timestamp now.
+    t2 := t1 + 1 milliseconds.
+    self assert:t2 = (t1 addMilliseconds:1).
+
+    t2 := t1 - 1 milliseconds.
+    self assert:t2 = (t1 addMilliseconds:-1).
+    self assert:t2 = (t1 subtractMilliseconds:1).
+
+    t1 := Timestamp now.
+    t2 := t1 + 1 microseconds.
+
+    self assert:t2 > t1.
+    self assert:t2 >= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 <= t1) not.
+    self assert:(t2 < t1) not.
+
+    t1 := Timestamp now.
+    t2 := t1 - 1 microseconds.
+
+    self assert:t2 < t1.
+    self assert:t2 <= t1.
+    self assert:(t2 = t1) not.
+    self assert:(t2 >= t1) not.
+    self assert:(t2 > t1) not.
+
+    t1 := Timestamp now.
+    t2 := t1 + 1 microseconds.
+    self assert:t2 = (t1 addMilliseconds:0.001).
+
+    t2 := t1 - 1 microseconds.
+    self assert:t2 = (t1 addMilliseconds:-0.001).
+    self assert:t2 = (t1 subtractMilliseconds:0.001).
+
+    "
+     self new test_20_comparing
+    "
+! !
+
+!TimeAndDateTest methodsFor:'tests-reading'!
+
+test_01a_ReadingTimes
+    self assert:(Time readFrom:'0:00'    ) = (Time hours:0 minutes:0 seconds:0).
+    self assert:(Time readFrom:'2:00'    ) = (Time hours:2 minutes:0 seconds:0).
+    self assert:(Time readFrom:'12:00'   ) = (Time hours:12 minutes:0 seconds:0).
+    self assert:(Time readFrom:'14:00'   ) = (Time hours:14 minutes:0 seconds:0).
+    self assert:(Time readFrom:'23:00'   ) = (Time hours:23 minutes:0 seconds:0).
+
+    self assert:(Time readFrom:'18:22:00') = (Time hours:18 minutes:22 seconds:0).
+    self assert:(Time readFrom:'14:00:11') = (Time hours:14 minutes:0 seconds:11).
+    self assert:(Time readFrom:'7:00:11' ) = (Time hours:7 minutes:0 seconds:11).
+    self assert:(Time readFrom:'0:00:00' ) = (Time hours:0 minutes:0 seconds:0).
+    self assert:(Time readFrom:'12:00:00') = (Time hours:12 minutes:0 seconds:0).
+    self assert:(Time readFrom:'0:00:00' ) = (Time hours:0 minutes:0 seconds:0).
+
+    self assert:(Time readFrom:'14'      ) = (Time hours:14 minutes:0 seconds:0).
+
+    self assert:(Time readFrom:'2 am'    ) = (Time hours:2 minutes:0 seconds:0).
+    self assert:(Time readFrom:'2 pm'    ) = (Time hours:14 minutes:0 seconds:0).
+
+    self assert:(Time readFrom:'2:30 am' ) = (Time hours:2 minutes:30 seconds:0).
+    self assert:(Time readFrom:'2:30 pm' ) = (Time hours:14 minutes:30 seconds:0).
+    self assert:(Time readFrom:'12:05 pm') = (Time hours:12 minutes:5 seconds:0).
+    self assert:(Time readFrom:'12:06 am') = (Time hours:0 minutes:6 seconds:0).
+
+    self assert:(Time readFrom:'6:22:00 pm' ) = (Time hours:18 minutes:22 seconds:0).
+    self assert:(Time readFrom:'2:00:11 pm' ) = (Time hours:14 minutes:0 seconds:11).
+    self assert:(Time readFrom:'7:00:11 am' ) = (Time hours:7 minutes:0 seconds:11).
+    self assert:(Time readFrom:'12:00:00 am') = (Time hours:0 minutes:0 seconds:0).
+    self assert:(Time readFrom:'0:00:00 am' ) = (Time hours:0 minutes:0 seconds:0).
+    self assert:(Time readFrom:'12:00:00 pm') = (Time hours:12 minutes:0 seconds:0).
+    self assert:(Time readFrom:'0:00:00 pm' onError:'invalid') = 'invalid'.
+
+    self assert:(Time readFrom:'24:00'   ) = (Time hours:0 minutes:0 seconds:0).
+    self assert:(Time readFrom:'24:00:00') = (Time hours:0 minutes:0 seconds:0).
+
+    self should:[Time readFrom:'24:00:00 am' ] raise:TimeConversionError.
+    self should:[Time readFrom:'24:00:00 pm' ] raise:TimeConversionError.
+
+    "
+     self new test_01a_ReadingTimes
+    "
+
+    "Created: / 09-11-2017 / 10:17:37 / cg"
+!
+
+test_01b_ReadingTimeDurations
+    self assert:(TimeDuration readFrom:'0:00'    ) = (TimeDuration hours:0 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'2:00'    ) = (TimeDuration hours:2 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'12:00'   ) = (TimeDuration hours:12 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'14:00'   ) = (TimeDuration hours:14 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'23:00'   ) = (TimeDuration hours:23 minutes:0 seconds:0).
+
+    self assert:(TimeDuration readFrom:'18:22:00') = (TimeDuration hours:18 minutes:22 seconds:0).
+    self assert:(TimeDuration readFrom:'14:00:11') = (TimeDuration hours:14 minutes:0 seconds:11).
+    self assert:(TimeDuration readFrom:'7:00:11' ) = (TimeDuration hours:7 minutes:0 seconds:11).
+    self assert:(TimeDuration readFrom:'0:00:00' ) = (TimeDuration hours:0 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'12:00:00') = (TimeDuration hours:12 minutes:0 seconds:0).
+    self assert:(TimeDuration readFrom:'0:00:00' ) = (TimeDuration hours:0 minutes:0 seconds:0).
+
+    self assert:(TimeDuration readFrom:'14'      ) = (TimeDuration hours:0 minutes:0 seconds:14).
+
+    "
+     self new test_01b_ReadingTimeDurations
+    "
+
+    "Created: / 09-11-2017 / 10:16:58 / cg"
+!
+
+test_01c_ReadingTimeStamps
+    |t|
+
+    self assert:(Timestamp readFrom:'2017-11-09 10:18:03.236') = (Timestamp year:2017 month:11 day:9 hour:10 minute:18 second:3 millisecond:236).
+
+    "/ standard format
+    self assert:(Timestamp readFrom:'2017-11-09') = (Timestamp year:2017 month:11 day:9 hour:0 minute:0 second:0).
+
+    "/ US format
+    self assert:(Timestamp readFrom:'12/09/2017') = (Timestamp year:2017 month:12 day:9 hour:0 minute:0 second:0).
+
+    "/ european format
+    self assert:(Timestamp readFrom:'9.11.2017') = (Timestamp year:2017 month:11 day:9 hour:0 minute:0 second:0).
+
+    "/ explicit format
+    self assert:(Timestamp readFrom:'9-nov-2017') = (Timestamp year:2017 month:11 day:9 hour:0 minute:0 second:0).
+    "/ explicit format
+    self assert:(Timestamp readFrom:'9. nov 2017') = (Timestamp year:2017 month:11 day:9 hour:0 minute:0 second:0).
+    "/ explicit format
+    self assert:(Timestamp readFrom:'9 nov 2017') = (Timestamp year:2017 month:11 day:9 hour:0 minute:0 second:0).
+
+    "/ milliseconds
+    t := Timestamp readFrom:'2017-11-09 10:18:03.123'.
+    self assert:(t milliseconds = 123).
+
+    "/ microseconds
+    t := Timestamp readFrom:'2017-11-09 10:18:03.123456'.
+    self assert:(t microseconds = 123456).
+
+    "/ nanoseconds
+    t := Timestamp readFrom:'2017-11-09 10:18:03.123456789'.
+    self assert:(t nanoseconds = 123456789).
+
+    "/ picoseconds
+    t := Timestamp readFrom:'2017-11-09 10:18:03.123456789012'.
+    self assert:(t picoseconds = 123456789012).
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06' format:'%day-%month-%year %h:%m:%s' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:0). 
+    self assert:(t := Timestamp readFrom:'20021995131106' format:'%2d%2month%4y%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6  millisecond:0). 
+    self assert:(t := Timestamp readFrom:'200295131106' format:'%2d%2month%2y%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:95 month:2 day:20 hour:13 minute:11 second:6  millisecond:0). 
+    self assert:(t := Timestamp readFrom:'200260131106' format:'%2d%2month%2(y1900)%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:1960 month:2 day:20 hour:13 minute:11 second:6 millisecond:0). 
+    self assert:(t := Timestamp readFrom:'200260131106' format:'%2d%2month%2(y2000)%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:2060 month:2 day:20 hour:13 minute:11 second:6 millisecond:0). 
+    self assert:(t := Timestamp readFrom:'200260131106' format:'%2d%2month%2(y1950)%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:1960 month:2 day:20 hour:13 minute:11 second:6 millisecond:0). 
+    self assert:(t := Timestamp readFrom:'200260131106' format:'%2d%2month%2(y1980)%2h%2m%2s' language:nil onError:[self error]
+                ) = (Timestamp year:2060 month:2 day:20 hour:13 minute:11 second:6 millisecond:0). 
+    self assert:(t := Timestamp readFrom:'March 7 2009 2:30pm ' format:'%monthName %day %year %u:%m%a' language:#en onError:[self error]
+                ) = (Timestamp year:2009 month:3 day:7 hour:14 minute:30 second:0 millisecond:0). "/ EST is 5hrs behind
+    self assert:(t := Timestamp readFrom:'March 7 2009 2:30am ' format:'%monthName %day %year %u:%m%a' language:#en onError:[self error]
+                ) = (Timestamp year:2009 month:3 day:7 hour:2 minute:30 second:0 millisecond:0). "/ EST is 5hrs behind
+
+    "/ Timestamp readIso8601FormatFrom:'20090307T183000-05'
+    "/ Timestamp readIso8601FormatFrom:'20090307T233000Z'
+    self assert:(t := Timestamp readFrom:'March 7 2009 6:30pm EST' format:'%monthName %day %year %u:%m%a %tz' language:#en onError:[self error]
+                ) = (UtcTimestamp year:2009 month:3 day:7 hour:23 minute:30 second:0 millisecond:0). "/ EST is 5hrs behind
+
+    self assert:(t := Timestamp readFrom:'March 7 2009 7:30pm UTC' format:'%monthName %day %year %u:%m%a %tz' language:#en onError:[self error]
+                ) = (UtcTimestamp year:2009 month:3 day:7 hour:19 minute:30 second:0 millisecond:0). 
+
+    self assert:(t := Timestamp readFrom:'2015103' format:'%4y%3dayOfYear' onError:[self error]
+                ) = (Timestamp year:2015 month:4 day:13 hour:0 minute:0 second:0 millisecond:0). 
+    self assert:t asDate dayOfYear == 103.
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.999' format:'%day-%month-%year %h:%m:%s.%i' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:999). 
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.100' format:'%day-%month-%year %h:%m:%s.%i' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:100). 
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.010' format:'%day-%month-%year %h:%m:%s.%i' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:10). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.1' format:'%day-%month-%year %h:%m:%s.%f' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:100). 
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.01' format:'%day-%month-%year %h:%m:%s.%f' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:10). 
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.001' format:'%day-%month-%year %h:%m:%s.%f' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 millisecond:1). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.12345' format:'%day-%month-%year %h:%m:%s.%f' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 microsecond:123000). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.12345' format:'%day-%month-%year %h:%m:%s.%F' language:nil onError:[self error]
+                ) = (Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6 microsecond:123450). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.12345678' format:'%day-%month-%year %h:%m:%s.%F' language:nil onError:[self error]
+                ) = ((Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6)+123456780 nanoseconds). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.123456' format:'%day-%month-%year %h:%m:%s.%F' language:nil onError:[self error]
+                ) = ((Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6)+123456 microseconds). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.123456789' format:'%day-%month-%year %h:%m:%s.%F' language:nil onError:[self error]
+                ) = ((Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6)+123456789 nanoseconds). 
+
+    self assert:(t := Timestamp readFrom:'20-2-1995 13:11:06.123456789012' format:'%day-%month-%year %h:%m:%s.%F' language:nil onError:[self error]
+                ) = ((Timestamp year:1995 month:2 day:20 hour:13 minute:11 second:6)+123456789012 picoseconds). 
+
+    "
+     self new test_01c_ReadingTimeStamps
+    "
+
+    "Created: / 09-11-2017 / 10:19:19 / cg"
+    "Modified: / 27-07-2018 / 09:07:58 / Stefan Vogel"
+!
+
+test_01d_ReadingTimeStamps
+    |t|
+
+    self assert:(t := Timestamp readFrom:'2017-11-09 10:18:03.236') printStringIso8601Format = '2017-11-09T10:18:03.236'.
+    self assert:(t isLocalTimestamp).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp not).
+    
+    self assert:(t := Timestamp readFrom:'2017-11-09 10:18:03.236Z') printStringIso8601Format = '2017-11-09T10:18:03.236Z'.
+    self assert:(t isLocalTimestamp not).
+    self assert:(t isUtcTimestamp).
+    self assert:(t isTZTimestamp not).
+
+    self should:[ Timestamp readFrom:'2017-11-09 10:18:03.236+1'] raise:Error.
+    self should:[ Timestamp readIso8601FormatFrom:'2017-11-09 10:18:03.236+1'] raise:TimeConversionError.
+    
+    self assert:(t := Timestamp readFrom:'2017-11-09 10:18:03.236+01') printStringIso8601Format = '2017-11-09T10:18:03.236+01'.
+    self assert:(t isLocalTimestamp not).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp).
+
+    "
+     self new test_01d_ReadingTimeStamps
+    "
+
+    "Created: / 24-05-2018 / 17:45:08 / Claus Gittinger"
+!
+
+test_01e_ReadingTimeStamps
+    |t|
+
+    self assert:(t := Timestamp readFrom:'1995-10-20T12:10:00.000') printStringIso8601Format = '1995-10-20T12:10:00'.  
+    self assert:(t isLocalTimestamp).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp not).
+
+    self assert:(t := Timestamp readFrom:'1995-10-20T12:10:00.010') printStringIso8601Format = '1995-10-20T12:10:00.010'.  
+    self assert:(t isLocalTimestamp).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp not).
+
+    self assert:(t := Timestamp readFrom:'2018-03-30T03:24:00') printStringIso8601Format = '2018-03-30T03:24:00'.  
+    self assert:(t isLocalTimestamp).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp not).
+
+    self assert:(t := Timestamp readFrom:'2018-3-30T03:24:00') printStringIso8601Format = '2018-03-30T03:24:00'.   
+    self assert:(t isLocalTimestamp).
+    self assert:(t isUtcTimestamp not).
+    self assert:(t isTZTimestamp not).
+
+    "
+     self new test_01e_ReadingTimeStamps
+    "
+
+    "Created: / 24-05-2018 / 17:45:08 / Claus Gittinger"
+!
+
+test_02_ReadingDates
+
+     self assert:(Date
+		    readFrom:'2-may-2010'
+		    printFormat:'%d-%shortMonthName-%y'
+		    language:'en'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+    {
+	{   '3-jan-2012'   .   (Date newDay:3 month:1 year:2012)    } .
+	{   '15-feb-2012'   .   (Date newDay:15 month:2 year:2012)  } .
+	{   '06-mar-2011'   .   (Date newDay:6 month:3 year:2011)   } .
+	{   '19-apr-2013'   .   (Date newDay:19 month:4 year:2013)  } .
+	{   '21-may-2015'   .   (Date newDay:21 month:5 year:2015)  } .
+	{   '21-jun-2015'   .   (Date newDay:21 month:6 year:2015)  } .
+	{   '21-jul-2015'   .   (Date newDay:21 month:7 year:2015)  } .
+	{   '21-aug-2015'   .   (Date newDay:21 month:8 year:2015)  } .
+	{   '21-sep-2015'   .   (Date newDay:21 month:9 year:2015)  } .
+	{   '21-oct-2015'   .   (Date newDay:21 month:10 year:2015)  } .
+	{   '21-nov-2015'   .   (Date newDay:21 month:11 year:2015)  } .
+	{   '21-dec-2015'   .   (Date newDay:21 month:12 year:2015)  } .
+    } do:[:eachTestPair |
+	 self assert:(Date
+			readFrom:(eachTestPair first)
+			printFormat:'%d-%shortMonthName-%y'
+			language:'en'
+			onError:[self error]
+		      ) = (eachTestPair second).
+    ].
+
+     self assert:(Date
+		    readFrom:'2-may-2010'
+		    printFormat:'%d-%monthName-%y'
+		    language:'en'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+     self assert:(Date
+		    readFrom:'2-may-2010'
+		    printFormat:'%d-%(shortMonthName)-%y'
+		    language:'en'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+     self assert:(Date
+		    readFrom:'2-may-2010'
+		    printFormat:'%d-%(monthName)-%y'
+		    language:'en'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+     self assert:(Date
+		    readFrom:'2-5-2010'
+		    printFormat:'%d-%m-%y'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+     self assert:(Date
+		    readFrom:'5/2/2010'
+		    printFormat:'%m/%d/%y'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+     self assert:(Date
+		    readFrom:'2010-5-2'
+		    printFormat:'%y-%m-%d'
+		    onError:[self error]
+		  ) = (Date newDay:2 month:5 year:2010).
+
+    "
+     self new test_02_ReadingDates
+    "
+!
+
 test_06_readingISO8601
     {
 	{ '2004-W53-6'  . 'sat' . (Date newDay:1 month:1 year:2005) }   .
@@ -475,27 +1013,6 @@
     "
 !
 
-test_10_readingISO8601_time
-    "/ the old ISO8601Builder tests moved to here
-
-    | ts reader |
-
-    reader := Timestamp::TimestampISO8601Builder.
-
-    ts := UtcTimestamp  year: 2005 month: 6 day: 15 hour: 17 minute: 37 second: 0 millisecond: 0.
-    self assert: ts = (reader read: '2005-06-15 17:37' withClass:UtcTimestamp).
-    self assert: ts = (reader read: '20050615T1737' withClass:UtcTimestamp).
-    self assert: ts = (reader read: '05-0615T17:3700' withClass:UtcTimestamp).
-
-    ts := UtcTimestamp  year: 2005 month: 6 day: 15 hour: 17 minute: 37 second: 0 millisecond: 30.
-    self assert: ts = (reader read: '05-0615T17:3700.03' withClass:UtcTimestamp).
-    self assert: ts = (reader read: '2005-06-15T17:37:00.0305486-00:00' withClass:UtcTimestamp).
-
-    "
-     self new test_10_readingISO8601_time
-    "
-!
-
 test_11_readingISO8601_timezone
     "/ the old ISO8601Builder tests moved to here
 
@@ -518,215 +1035,6 @@
     "
 !
 
-test_12_dateQueries
-    |d1 d2 d3|
-
-    d1 := Date newDay:1 month:2 year:1940.
-    d2 := Date newDay:1 month:2 year:1941.
-    self assert:(d2 - d1) = 366.
-
-    d1 := Date newDay:1 month:2 year:1840.
-    d2 := Date newDay:1 month:2 year:1841.
-    self assert:(d2 - d1) = 366.
-    self assert:(d1 addDays:366) = d2.
-
-    Date leapYear:1540.
-    d1 := Date newDay:1 month:2 year:1540.
-    d2 := Date newDay:1 month:2 year:1541.
-    self assert:(d2 - d1) = 366.
-
-    d1 := Date newDay:1 year:1901.
-    self assert:(d1 day = 1).
-    self assert:(d1 month = 1).
-    self assert:(d1 year = 1901).
-
-    "/ 1900 was NOT a leap year
-    self assert:(Date leapYear:1900) not.
-    "/ 2000 was a leap year
-    self assert:(Date leapYear:2000).
-
-    d2 := d1 subtractDays:365.
-    self assert:(d2 day = 1).
-    self assert:(d2 month = 1).
-    self assert:(d2 year = 1900).
-
-    d3 := d2 subtractDays:365.
-    self assert:(d3 day = 1).
-    self assert:(d3 month = 1).
-    self assert:(d3 year = 1899).
-
-    d1 := Date newDay:1 month:2 year:2540.
-    d2 := Date newDay:1 month:2 year:2541.
-    self assert:(d2 - d1) = 366.
-
-
-    "
-     self new test_12_dateQueries
-    "
-!
-
-test_13_timestampQueries
-    |d1 d2 local utc|
-
-    d1 := UtcTimestamp newDay:1 month:1 year:2000.
-    d2 := UtcTimestamp newDay:1 month:1 year:2001.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := UtcTimestamp newDay:2 month:1 year:1940.
-    d2 := UtcTimestamp newDay:2 month:1 year:1941.
-    self assert:d1 asDate year = 1940.
-    self assert:d2 asDate year = 1941.
-    self assert:d1 asDate month = 1.
-    self assert:d2 asDate month = 1.
-    self assert:d1 asDate day = 2.
-    self assert:d2 asDate day = 2.
-
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := UtcTimestamp newDay:1 month:1 year:1840.
-    d2 := UtcTimestamp newDay:1 month:1 year:1841.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    self assert:(d1 addDays:366) = d2.
-
-    d1 := UtcTimestamp newDay:1 month:1 year:1540.
-    d2 := UtcTimestamp newDay:1 month:1 year:1541.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := Timestamp newDay:1 month:1 year:1540.
-    d2 := Timestamp newDay:1 month:1 year:1541.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := Timestamp newDay:1 month:1 year:2038.
-    d2 := Timestamp newDay:1 month:1 year:2039.
-    self assert:d1 asDate isLeapYear not.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 365.
-
-    d1 := Timestamp newDay:1 month:1 year:2540.
-    d2 := Timestamp newDay:1 month:1 year:2541.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := Timestamp newDay:1 month:1 year:3540.
-    d2 := Timestamp newDay:1 month:1 year:3541.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := Timestamp newDay:1 month:1 year:1969.
-    d2 := Timestamp newDay:1 month:1 year:1970.   
-    self assert:d1 asDate isLeapYear not.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 365.
-
-    d1 := Timestamp newDay:1 month:1 year:1600.
-    d2 := Timestamp newDay:1 month:1 year:1601.   
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    d1 := Timestamp newDay:1 month:1 year:1969.
-    d2 := Timestamp newDay:1 month:1 year:1970.
-    self assert:d1 asDate isLeapYear not.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 365.
-
-    d1 := Timestamp newDay:1 month:1 year:1600.
-    d2 := Timestamp newDay:1 month:1 year:1601.
-    self assert:d1 asDate isLeapYear.
-    self assert:d2 asDate isLeapYear not.
-    self assert:(d2 - d1) days = 366.
-
-    "/ local time vs. utc time
-    local := Timestamp newDay:1 month:1 year:1940.
-    utc := UtcTimestamp newDay:1 month:1 year:1940.
-    self assert:(local asUtcTimestamp - utc asUtcTimestamp) asSeconds = local utcOffset.
-
-    "/ tz time vs. utc time
-    utc := Timestamp readFrom:'20000102T123000Z'.
-    local := Timestamp readFrom:'20000102T123000+02'.
-    self assert:(utc - local) asSeconds = 7200.
-
-    "/ tz time vs. utc time
-    utc := UtcTimestamp readFrom:'20000102T123000Z'.
-    local := UtcTimestamp readFrom:'20000102T123000-02'.
-    self assert:(utc - local) asSeconds = -7200.
-
-    "
-     self new test_13_timestampQueries
-    "
-!
-
-test_14_arithmetic
-    |t1 t2 t3 s|
-
-    t1 := UtcTimestamp newDay:1 month:1 year:2000.
-    t2 := t1 addDays:1.
-    self assert:(t2 - t1) days = 1.
-
-    t2 := t1 addHours:1.
-    self assert:(t2 - t1) hours = 1.
-
-    t2 := t1 addSeconds:1.
-    self assert:(t2 - t1) seconds = 1.
-
-    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
-    t2 := t1 addDays:1.
-    self assert:(t2 printString = '2000-01-03 13:30:45Z').
-
-    t1 := Timestamp readFrom:'20000102T133045+01'.
-    t2 := t1 addDays:1.
-    self assert:(t2 printString = '2000-01-03 13:30:45+01').
-
-    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
-    t2 := Timestamp readFrom:'20000102T133045Z'.
-    self assert:(t1 = t2).
-
-    t2 := Timestamp readFrom:'20000102T143045+01'.
-    self assert:(t1 = t2).
-
-    t2 := Timestamp readFrom:'20000102T123045-01'.
-    self assert:(t1 = t2).
-
-    t2 := Timestamp readFrom:'20000102T123045'.     "/ a local one
-    s := t2 storeString.
-    t3 := Timestamp readFrom:s.
-
-    self assert:(t2 = t3).
-
-    t1 := TZTimestamp readFrom:'20000102T133045Z'.
-    self assert:(t1 printString = '2000-01-02 13:30:45+00').
-    t1 := UtcTimestamp readFrom:'20000102T133045Z'.
-    self assert:(t1 printString = '2000-01-02 13:30:45Z').
-
-    "
-     self new test_14_arithmetic
-    "
-!
-
-test_15_misc
-    #( 1700  1800  1900  2100  2200 ) do:[:y |
-	self assert:(Date leapYear:y) not
-    ].
-    #( 1600  2000 2400 ) do:[:y |
-	self assert:(Date leapYear:y)
-    ].
-
-    "
-     self new test_15_misc
-    "
-!
-
 test_16_readingOtherFormats
     | ts |
 
@@ -753,6 +1061,87 @@
     "
      self new test_16_readingOtherFormats
     "
+!
+
+test_17_readingBrokenStrings
+    "endless loop happened with:
+        Timestamp readFrom:'0' onError:#foo
+    "
+    
+    #(
+        ''
+        '0'
+        '1'
+        '1-'
+        '1-1'
+        '1-1-'
+        '1-1-1 10'
+        '0-0-0'
+    ) do:[:eachBadString |    
+        | ts |
+
+        "/ should not run into an endless loop
+        [
+            ts := Timestamp readFrom:eachBadString onError:#foo.
+        ] valueWithTimeout:(50 milliseconds).
+    
+        self assert: (ts notNil) description:'timestamp reading leads to endless loop'.
+        self assert: ts == #foo.
+    ].
+    
+    "
+     self new test_17_readingBrokenStrings
+    "
+
+    "Created: / 09-11-2017 / 10:00:30 / cg"
+!
+
+test_21_readingDateInVariousFormats
+    {
+        '1.1.1990' . '%d %m %y' . (Date year:1990 month:1 day:1 ) .
+        '1.1.2090' . '%d %m %y' . (Date year:2090 month:1 day:1 ) .
+
+        '1.1.49' . '%d %m %(Y1950)' . (Date year:2049 month:1 day:1 ) .
+        '1.1.50' . '%d %m %(Y1950)' . (Date year:1950 month:1 day:1 ) .
+        '1.1.51' . '%d %m %(Y1950)' . (Date year:1951 month:1 day:1 ) .
+        '1.1.99' . '%d %m %(Y1950)' . (Date year:1999 month:1 day:1 ) .
+
+        '1.1.69' . '%d %m %(Y1970)' . (Date year:2069 month:1 day:1 ) .
+        '1.1.70' . '%d %m %(Y1970)' . (Date year:1970 month:1 day:1 ) .
+        '1.1.71' . '%d %m %(Y1970)' . (Date year:1971 month:1 day:1 ) .
+        '1.1.99' . '%d %m %(Y1970)' . (Date year:1999 month:1 day:1 ) .
+
+        '1.1.79' . '%d %m %(Y1980)' . (Date year:2079 month:1 day:1 ) .
+        '1.1.80' . '%d %m %(Y1980)' . (Date year:1980 month:1 day:1 ) .
+        '1.1.81' . '%d %m %(Y1980)' . (Date year:1981 month:1 day:1 ) .
+        '1.1.99' . '%d %m %(Y1980)' . (Date year:1999 month:1 day:1 ) .
+
+        '1.1.49' . '%d %m %(Y1900)' . (Date year:1949 month:1 day:1 ) .
+        '1.1.69' . '%d %m %(Y1900)' . (Date year:1969 month:1 day:1 ) .
+        '1.1.79' . '%d %m %(Y1900)' . (Date year:1979 month:1 day:1 ) .
+        '1.1.80' . '%d %m %(Y1900)' . (Date year:1980 month:1 day:1 ) .
+        '1.1.81' . '%d %m %(Y1900)' . (Date year:1981 month:1 day:1 ) .
+        '1.1.99' . '%d %m %(Y1900)' . (Date year:1999 month:1 day:1 ) .
+
+        '1.1.49' . '%d %m %(Y2000)' . (Date year:2049 month:1 day:1 ) .
+        '1.1.69' . '%d %m %(Y2000)' . (Date year:2069 month:1 day:1 ) .
+        '1.1.79' . '%d %m %(Y2000)' . (Date year:2079 month:1 day:1 ) .
+        '1.1.80' . '%d %m %(Y2000)' . (Date year:2080 month:1 day:1 ) .
+        '1.1.81' . '%d %m %(Y2000)' . (Date year:2081 month:1 day:1 ) .
+        '1.1.99' . '%d %m %(Y2000)' . (Date year:2099 month:1 day:1 ) .
+    } inGroupsOf:3 do:[:str :fmt :expected |    
+        | result |
+
+        result := Date readFrom:str format:fmt onError:#foo.
+    
+        self assert: result = expected.
+    ].
+    
+    "
+     self new test_21_readingDateInVariousFormats
+    "
+
+    "Created: / 09-11-2017 / 10:00:30 / cg"
 ! !
 
 !TimeAndDateTest class methodsFor:'documentation'!