RegressionTests__TimeAndDateTest.st
author Jan Vrany <jan.vrany@labware.com>
Thu, 25 Aug 2022 11:29:18 +0100
branchjv
changeset 2607 ddf2eb8b3f1d
parent 2597 9496e0bdef34
permissions -rwxr-xr-x
Fix Windows tests for long paths in `exec:environment:...` This commit makes `Win32OperatingSystemTests >> testExec...` more robust by testing the error code rather than text of the exception which may change.

"
COPYRIGHT (c) 2021 LabWare

              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:goodies/regression' }"

"{ NameSpace: RegressionTests }"

TestCase subclass:#TimeAndDateTest
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'tests-Regression-DateAndTime'
!

!TimeAndDateTest class methodsFor:'documentation'!

copyright
"
COPYRIGHT (c) 2021 LabWare

              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
! !

!TimeAndDateTest methodsFor:'Testing'!

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.

    self assert:(Date newDay:4 month:11 year:2012) weekInYear == 44.
    self assert:(Date newDay:12 month:11 year:2012) weekInYear == 46.

    self assert:(Date newDay:29 month:12 year:2014) weekInYear == 1.    "/ YES!!
    self assert:(Date newDay:30 month:12 year:2014) weekInYear == 1.    "/ YES!!
    self assert:(Date newDay:31 month:12 year:2014) weekInYear == 1.    "/ YES!!
    self assert:(Date newDay:1 month:1 year:2015) weekInYear == 1.
    self assert:(Date newDay:2 month:1 year:2015) weekInYear == 1.
    self assert:(Date newDay:3 month:1 year:2015) weekInYear == 1.
    self assert:(Date newDay:4 month:1 year:2015) weekInYear == 1.

    self assert:(Date newDay:5 month:1 year:2015) weekInYear == 2.

    "/ every 4th of january is in the 1st week
    1902 to:2100 do:[:y |
	|d|
	d := Date newDay:4 month:1 year:y.
	self assert:d weekInYear == 1.
    ].

    "
     self new test_03_calenderWeek
    "
!

test_04_calenderWeek_fails
    <test: broken>
^ self.
    "/ currently fails for date before 1901
    1900 to:1905 do:[:y |
	|d|
	d := Date newDay:4 month:1 year:y.
	self assert:d weekInYear == 1.
    ].

    "
     self new test_04_calenderWeek_fails
    "
!

test_05_weekDayConversion
    {
	{ #( 6 53 2004) "2004-W53-6" . (Date newDay:1 month:1 year:2005) }   .
	{ #( 7 53 2004) "2004-W53-7" . (Date newDay:2 month:1 year:2005) }   .
	{ #( 6 52 2005) "2005-W52-6" . (Date newDay:31 month:12 year:2005) } .
	{ #( 1 1  2007) "2007-W01-1" . (Date newDay:1 month:1 year:2007) }   .
	{ #( 7 52 2007) "2007-W52-7" . (Date newDay:30 month:12 year:2007) } .

	{ #( 1 1  2008) "2008-W01-1" . (Date newDay:31 month:12 year:2007) } .
	{ #( 2 1  2008) "2008-W01-2" . (Date newDay:1 month:1 year:2008) }   .
	{ #( 7 52 2008) "2008-W52-7" . (Date newDay:28 month:12 year:2008) } .

	{ #( 1 1  2009) "2009-W01-1" . (Date newDay:29 month:12 year:2008) }     .
	{ #( 2 1  2009) "2009-W01-2" . (Date newDay:30 month:12 year:2008) }     .
	{ #( 3 1  2009) "2009-W01-3" . (Date newDay:31 month:12 year:2008) }     .
	{ #( 4 1  2009) "2009-W01-4" . (Date newDay:1 month:1 year:2009) }       .

	{ #( 4 53 2009) "2009-W53-4" . (Date newDay:31 month:12 year:2009) }     .
	{ #( 5 53 2009) "2009-W53-5" . (Date newDay:1 month:1 year:2010) }       .
	{ #( 6 53 2009) "2009-W53-6" . (Date newDay:2 month:1 year:2010) }       .
	{ #( 7 53 2009) "2009-W53-7" . (Date newDay:3 month:1 year:2010) }       .

	{ #( 1 1  1997) "1997-W01-1" . (Date newDay:30 month:12 year:1996) } .
    } do:[:eachPair |
	|dwy d1 d2 dayInWeek weekNr year|

	dwy := eachPair first.
	dayInWeek := dwy first.
	weekNr := dwy second.
	year := dwy third.
	d1 := Date newDayInWeek:dayInWeek week:weekNr year:year.

	d2 := eachPair second.
	self assert:(d1 = d2) description:'wrong: ',d1 printString, ' vs. ',d2 printString.
	self assert:(d1 weekInYear == weekNr).
	self assert:(d1 dayInWeek == dayInWeek).
    ]

    "
     self new test_05_weekDayConversion
    "
!

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:2.
    d2 := UtcTimestamp year:1970 month:1 day:2.
    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"
    "Modified: / 18-06-2021 / 16:21:55 / Jan Vrany <jan.vrany@labware.com>"
!

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) }   .
	{ '2004-W53-7'  . 'sun' . (Date newDay:2 month:1 year:2005) }   .
	{ '2005-W52-6'  . 'sat' . (Date newDay:31 month:12 year:2005) } .
	{ '2007-W01-1'  . 'mon' . (Date newDay:1 month:1 year:2007) }   .
	{ '2007-W52-7'  . 'sun' . (Date newDay:30 month:12 year:2007) } .

	{ '2008-W01-1'  . 'mon' . (Date newDay:31 month:12 year:2007) } .
	{ '2008-W01-2'  . 'tue' . (Date newDay:1 month:1 year:2008) }   .
	{ '2008-W52-7'  . 'sun' . (Date newDay:28 month:12 year:2008) } .

	{ '2009-W01-1'  . 'mon' . (Date newDay:29 month:12 year:2008) }     .
	{ '2009-W01-2'  . 'tue' . (Date newDay:30 month:12 year:2008) }     .
	{ '2009-W01-3'  . 'wed' . (Date newDay:31 month:12 year:2008) }     .
	{ '2009-W01-4'  . 'thu' . (Date newDay:1 month:1 year:2009) }       .

	{ '2009-W53-4'  . 'thu' . (Date newDay:31 month:12 year:2009) }     .
	{ '2009-W53-5'  . 'fri' . (Date newDay:1 month:1 year:2010) }       .
	{ '2009-W53-6'  . 'sat' . (Date newDay:2 month:1 year:2010) }       .
	{ '2009-W53-7'  . 'sun' . (Date newDay:3 month:1 year:2010) }       .
    } do:[:eachTriple |
	|input expected expectedDayName got gotName|

	input := eachTriple first.
	expectedDayName := eachTriple second.
	expected := eachTriple third.
	got := (Timestamp readIso8601FormatFrom:input onError:nil) asDate.
	self assert:(got = expected) description:'wrong: ',input.
	gotName := got abbreviatedDayNameForLanguage:#en.
	self assert:gotName = expectedDayName description:'expected: ',expectedDayName asString,' got: ',gotName asString.
    ]

    "
     self new test_06_calenderWeek_fails
    "
!

test_07_readingISO8601
    "tests reading into a 'natural' timestamp - that is if there was a TZ info,
     that will be printed. If not, it will remain a local timestamp.
     Presenting timestamps this way is not usually a good idea, except for GUI
     (but not for data exchange)"

    {
     { '1995-02-20T13:11:06.123'   . '1995-02-20 13:11:06.123' } .
     { '1995-02-20T13:11:06'       . '1995-02-20 13:11:06' } .
     { '1995-02T13:11:06'          . '1995-02-01 13:11:06' } .
     { '1995T13:11:06'             . '1995-01-01 13:11:06' } .
     { '1995T13:11'                . '1995-01-01 13:11:00' } .
     { '1995T13:11.5'              . '1995-01-01 13:11:30' } .
     { '1995T13:11,5'              . '1995-01-01 13:11:30' } .
     { '1995T13'                   . '1995-01-01 13:00:00' } .
     { '1995T13.25'                . '1995-01-01 13:15:00' } .
     { '1995T13.333333'            . '1995-01-01 13:19:59.999' } .
     { '1995'                      . '1995-01-01 00:00:00' } .
     { '1995-02'                   . '1995-02-01 00:00:00' } .
     { '19950204'                  . '1995-02-04 00:00:00' } .

     "/ day in year
     { '1995-001'                  . '1995-01-01 00:00:00' } .
     { '1995-035'                  . '1995-02-04 00:00:00' } .
     { '1995035'                   . '1995-02-04 00:00:00' } .

     { '1997-01-01'                . '1997-01-01 00:00:00' } .
     "/ week and weekday
     { '1997-W01'                  . '1996-12-30 00:00:00' } .
     { '1997W01'                   . '1996-12-30 00:00:00' } .
     { '1997W01-1'                 . '1996-12-30 00:00:00' } .
     { '1997W011'                  . '1996-12-30 00:00:00' } .
     { '1997W01'                   . '1996-12-30 00:00:00' } .
     { '1997W01-2'                 . '1996-12-31 00:00:00' } .
     { '1997-W01-2'                . '1996-12-31 00:00:00' } .
     { '1997W012'                  . '1996-12-31 00:00:00' } .
     { '2014W40'                   . '2014-09-29 00:00:00' } .
     { '2014W44-4'                 . '2014-10-30 00:00:00' } .
     { '2014W01'                   . '2013-12-30 00:00:00' } .
     { '2014W01-1'                 . '2013-12-30 00:00:00' } .
     { '2014W01-2'                 . '2013-12-31 00:00:00' } .
     { '2014W01-3'                 . '2014-01-01 00:00:00' } .

     { '1995-02-20 13:11'          . '1995-02-20 13:11:00' } .
     { '1995-02-20 1311'           . '1995-02-20 13:11:00' } .
     { '1995-02-20 13'             . '1995-02-20 13:00:00' } .
     { '1995-02-20 235959'         . '1995-02-20 23:59:59' } .
     { '19950220 235959'           . '1995-02-20 23:59:59' } .
     { '19950220 23:59:59.9942'    . '1995-02-20 23:59:59.994' } .
     { '19950220 235959.9942'      . '1995-02-20 23:59:59.994' } .

     "/ local vs. UTC
     { '1995-02-20 13:11:06'       . '1995-02-20 13:11:06' } .
     { '1995-02-20 13:11:06Z'      . '1995-02-20 13:11:06Z' } .
     { '1995-02-20 13:11:06+01'    . '1995-02-20 13:11:06+01' } .
     { '1995-02-20 13:11:06+01:00' . '1995-02-20 13:11:06+01' } .
     { '1995-02-20 13:11:06+01:30' . '1995-02-20 13:11:06+01:30' } .
     { '1995-02-20 13:11:06+0130'  . '1995-02-20 13:11:06+01:30' } .
     { '1995-02-20 13:11:06-01'    . '1995-02-20 13:11:06-01' } .
     { '1995-02-20 13:11:06-01:00' . '1995-02-20 13:11:06-01' } .
     { '1995-02-20 13:11:06-01:30' . '1995-02-20 13:11:06-01:30' } .
     { '1995-02-20 13:11:06-0130'  . '1995-02-20 13:11:06-01:30' } .

     "/ 24 is allowed with ISO, and is 00:00 of the next day:
     { '1995-02-20 24:00:00'       . '1995-02-21 00:00:00' } .
    } do:[:eachPair |
	|s1 t expected got|

	s1 := eachPair first.
	t := Timestamp readIso8601FormatFrom:s1.
	expected := eachPair second.
	got := t asString.
	self assert:(got = expected) description:'expected: ',expected,' got:',got.
    ].

    "
     self new test_07_readingISO8601
    "
!

test_07b_readingISO8601UTC
    "tests reading into an utc timestamp"

    {
     { '1995-02-20T13:11:06.123'   . '1995-02-20 13:11:06.123Z' } .
     { '1995-02-20T13:11:06'       . '1995-02-20 13:11:06Z' } .
     { '1995-02T13:11:06'          . '1995-02-01 13:11:06Z' } .
     { '1995T13:11:06'             . '1995-01-01 13:11:06Z' } .
     { '1995T13:11'                . '1995-01-01 13:11:00Z' } .
     { '1995T13:11.5'              . '1995-01-01 13:11:30Z' } .
     { '1995T13:11,5'              . '1995-01-01 13:11:30Z' } .
     { '1995T13'                   . '1995-01-01 13:00:00Z' } .
     { '1995T13.25'                . '1995-01-01 13:15:00Z' } .
     { '1995T13.333333'            . '1995-01-01 13:19:59.999Z' } .
     { '1995'                      . '1995-01-01 00:00:00Z' } .
     { '1995-02'                   . '1995-02-01 00:00:00Z' } .
     { '19950204'                  . '1995-02-04 00:00:00Z' } .

     "/ day in year
     { '1995-001'                  . '1995-01-01 00:00:00Z' } .
     { '1995-035'                  . '1995-02-04 00:00:00Z' } .
     { '1995035'                   . '1995-02-04 00:00:00Z' } .

     { '1997-01-01'                . '1997-01-01 00:00:00Z' } .
     "/ week and weekday
     { '1997-W01'                  . '1996-12-30 00:00:00Z' } .
     { '1997W01'                   . '1996-12-30 00:00:00Z' } .
     { '1997W01-1'                 . '1996-12-30 00:00:00Z' } .
     { '1997W011'                  . '1996-12-30 00:00:00Z' } .
     { '1997W01'                   . '1996-12-30 00:00:00Z' } .
     { '1997W01-2'                 . '1996-12-31 00:00:00Z' } .
     { '1997-W01-2'                . '1996-12-31 00:00:00Z' } .
     { '1997W012'                  . '1996-12-31 00:00:00Z' } .
     { '2014W40'                   . '2014-09-29 00:00:00Z' } .
     { '2014W44-4'                 . '2014-10-30 00:00:00Z' } .
     { '2014W01'                   . '2013-12-30 00:00:00Z' } .
     { '2014W01-1'                 . '2013-12-30 00:00:00Z' } .
     { '2014W01-2'                 . '2013-12-31 00:00:00Z' } .
     { '2014W01-3'                 . '2014-01-01 00:00:00Z' } .

     { '1995-02-20 13:11'          . '1995-02-20 13:11:00Z' } .
     { '1995-02-20 1311'           . '1995-02-20 13:11:00Z' } .
     { '1995-02-20 13'             . '1995-02-20 13:00:00Z' } .
     { '1995-02-20 235959'         . '1995-02-20 23:59:59Z' } .
     { '19950220 235959'           . '1995-02-20 23:59:59Z' } .
     { '19950220 23:59:59.9942'    . '1995-02-20 23:59:59.994Z' } .
     { '19950220 235959.9942'      . '1995-02-20 23:59:59.994Z' } .

     "/ local vs. UTC
     { '1995-02-20 13:11:06'       . '1995-02-20 13:11:06Z' } .
     { '1995-02-20 13:11:06Z'      . '1995-02-20 13:11:06Z' } .
     { '1995-02-20 13:11:06+01'    . '1995-02-20 12:11:06Z' } .      "/ notice the changed time here!!!!!!
     { '1995-02-20 13:11:06+01:00' . '1995-02-20 12:11:06Z' } .      "/ notice the changed time here!!!!!!
     { '1995-02-20 13:11:06+01:30' . '1995-02-20 11:41:06Z' } .      "/ notice the changed time here!!!!!!
     { '1995-02-20 13:11:06+0130'  . '1995-02-20 11:41:06Z' } .      "/ notice the changed time here!!!!!!
     { '1995-02-20 13:11:06-01'    . '1995-02-20 14:11:06Z' } .
     { '1995-02-20 13:11:06-01:00' . '1995-02-20 14:11:06Z' } .
     { '1995-02-20 13:11:06-01:30' . '1995-02-20 14:41:06Z' } .
     { '1995-02-20 13:11:06-0130'  . '1995-02-20 14:41:06Z' } .

     "/ 24 is allowed with ISO, and is 00:00 of the next day:
     { '1995-02-20 24:00:00'       . '1995-02-21 00:00:00Z' } .
    } do:[:eachPair |
	|s1 t expected got|

	s1 := eachPair first.
	t := UtcTimestamp readIso8601FormatFrom:s1.
	expected := eachPair second.
	got := t asString.
	self assert:(got = expected) description:'expected: ',expected,' got:',got.
    ].

    "
     self new test_07_readingISO8601
    "
!

test_08_readingISO8601_date
    "/ the old ISO8601Builder tests moved to here

    | ts reader |

    reader := Timestamp::TimestampISO8601Builder.

    ts := UtcTimestamp
	 year: 2005 month: 6 day: 15
	 hour: 0 minute: 0 second: 0 millisecond: 0.

    "Test common dates"
    self assert: ts = (reader read: '20050615' withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005-06-15'  withClass:UtcTimestamp).
    self assert: ts = (reader read: '05-06-15'  withClass:UtcTimestamp).
    self assert: ts = (reader read: '05-0615'  withClass:UtcTimestamp). "/ Is this correct?
    self assert: ts = (reader read: ':50615'  withClass:UtcTimestamp). "/ Should not happen and should not appear after 2009
    self assert: ts = (reader read: '200506-15'  withClass:UtcTimestamp). "/ Is this corect?
    self assert: ts = (reader read: '105-06-15'  withClass:UtcTimestamp). "/ Should not happen

    "Test week numbers"
    self assert: ts = (reader read: '05W243'  withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005W24-3'  withClass:UtcTimestamp).

    "Test day numbers"
    self assert: ts = (reader read: '2005-166'  withClass:UtcTimestamp).

    ts := UtcTimestamp year: 2004 month: 12 day: 31 hour: 0 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '2004-366'  withClass:UtcTimestamp).

    ts := UtcTimestamp year: 2005 month: 12 day: 31 hour: 0 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '2005-365'  withClass:UtcTimestamp).

    "Test february"
    ts := UtcTimestamp year: 2000 month: 2 day: 28 hour: 0 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '20000228'  withClass:UtcTimestamp).

    ts := UtcTimestamp year: 2000 month: 2 day: 29 hour: 0 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '20000229'  withClass:UtcTimestamp).

    "
     self new test_08_readingISO8601
    "
!

test_09_readingISO8601_edge
    "/ the old ISO8601Builder tests moved to here

    | ts reader |

    reader := Timestamp::TimestampISO8601Builder.

    self should: [reader read: '20050229' withClass:UtcTimestamp] raise:ConversionError.
    self should: [reader read: '20050029' withClass:UtcTimestamp] raise:ConversionError.
    self should: [reader read: '20050332' withClass:UtcTimestamp] raise:ConversionError.
    self should: [reader read: '2005-366' withClass:UtcTimestamp] raise:ConversionError.

    ts := UtcTimestamp year: 2005 month: 1 day: 1 hour: 0 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '20041231T22-0200' withClass:UtcTimestamp).

    ts := UtcTimestamp year: 2004 month: 12 day: 31 hour: 22 minute: 0 second: 0 millisecond: 0.
    self assert: ts = (reader read: '20050101T0000+0200' withClass:UtcTimestamp).

    "
     self new test_08_readingISO8601
    "
!

test_11_readingISO8601_timezone
    "/ 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-15T17:37Z' withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005-06-15T17:37+0000' withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005-06-15T17:37-00:00' withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005-06-15T15:37:00-0200' withClass:UtcTimestamp).
    self assert: ts = (reader read: '2005-06-15T19:37:00+0200'withClass:UtcTimestamp).

    "
     self new test_11_readingISO8601_timezone
    "
!

test_16_readingOtherFormats
    | ts |

    "/ european format
    ts := Timestamp readFrom: '16-09-2013 00:42:35' readStream.

    self assert: ts day = 16.
    self assert: ts month = 9.
    self assert: ts year = 2013.
    self assert: ts hours = 0.
    self assert: ts minutes = 42.
    self assert: ts seconds = 35.

    "/ us format
    ts := Timestamp readFrom: '11/21/2013 00:42:35' readStream.

    self assert: ts day = 21.
    self assert: ts month = 11.
    self assert: ts year = 2013.
    self assert: ts hours = 0.
    self assert: ts minutes = 42.
    self assert: ts seconds = 35.

    "
     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'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
!

version_HG

    ^ '$Changeset: <not expanded> $'
! !