Date.st
changeset 699 12f456343eea
parent 569 7134eb78cf48
child 972 76cd3ca837e4
--- a/Date.st	Thu Dec 07 22:24:46 1995 +0100
+++ b/Date.st	Thu Dec 07 22:32:39 1995 +0100
@@ -11,11 +11,10 @@
 "
 
 Magnitude subclass:#Date
-       instanceVariableNames:'dateEncoding'
-       classVariableNames:'DayNames MonthNames DayAbbrevs MonthAbbrevs
-			   EnvironmentChange'
-       poolDictionaries:''
-       category:'Magnitude-General'
+	 instanceVariableNames:'dateEncoding'
+	 classVariableNames:'DayNames MonthNames DayAbbrevs MonthAbbrevs EnvironmentChange'
+	 poolDictionaries:''
+	 category:'Magnitude-General'
 !
 
 !Date class methodsFor:'documentation'!
@@ -34,10 +33,6 @@
 "
 !
 
-version
-    ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.28 1995-11-16 23:27:56 cg Exp $'
-!
-
 documentation
 "
     Instances of Date represent dates as year, month and day encoded in the 
@@ -71,8 +66,522 @@
 "
 ! !
 
+!Date class methodsFor:'instance creation'!
+
+day:day month:month year:year
+    "return a new Date, given the day, month and year.
+     Obsolete:
+	use newDay:month:year: for ST-80 compatibility"
+
+    ^ self newDay:day month:month year:year
+!
+
+day:dayInYear year:year
+    "return a new Date, given the year and the day-in-year (starting at 1).
+     Obsolete:
+	use newDay:year: for ST-80 compatibility"
+
+    ^ self newDay:dayInYear year:year
+!
+
+fromDays:dayCount
+    "return a new Date, given the day-number starting with 0 at 1.Jan 1901;
+     (i.e. 'Date fromDays:0' returns 1st Jan. 1901).
+     Date asDays is the reverse operation.
+     for GNU/ST-80 compatibility"
+
+    |yr rest d|
+
+    "approx. year"
+    yr := (dayCount // 366) + 1901.
+    rest := dayCount - (self yearAsDays:yr) + 1. "+1 for ST-80 compatibility"
+    d := self daysInYear:yr.
+    (rest > d) ifTrue:[
+	"adjust"
+	yr := yr + 1.
+	rest := rest - d.
+    ].
+
+    ^ self day:rest year:yr
+
+    "
+     Date fromDays:0     -> 1 jan 1901
+     Date fromDays:365   -> 1 jan 1902
+     Date fromDays:730   -> 1 jan 1903
+     Date fromDays:1095  -> 1 jan 1903
+     Date fromDays:1460  ->31 dec 1904 since 1904 was a leap year
+    "
+!
+
+fromOSTime:osTime
+    "return a date, representing the date given by the operatingSystem time.
+     This somewhat clumsy implementation hides the OS's date representation
+     (i.e. makes this class independent of what the OS starts its time values with).
+     Dont use this method, the osTime representation is totally unportable."
+
+    ^ self basicNew fromOSTime:osTime
+
+    "
+     Date fromOSTime:#(0 0)      -> on UNIX: this should return 1st Jan 1970
+				    thats where Unix time starts
+				    On other systems, it may be something different.
+
+     Date fromOSTime:#(86400 0)  -> on UNIX: the day after
+    "
+!
+
+newDay:day month:month year:year
+    "return a new Date, given the day, month and year.
+     For your convenience, month may be either an integer 
+     or the months name as a string. 
+     Year may be the actual year (such as 1890, 2001) or the number 
+     of years since 1900 (which is rubbish ST-80 compatibility: 
+     it will be totally useless in a few years ...).
+     You better not use this short-year feature in your programs."
+
+    |monthIndex ok yr|
+
+    yr := year.
+    yr < 100 ifTrue:[
+	yr := yr + 1900.
+    ].
+
+    month isInteger ifTrue:[
+	monthIndex := month
+    ] ifFalse:[
+	monthIndex := self indexOfMonth:month
+    ].
+    (monthIndex == 2 and:[day == 29]) ifTrue:[
+	ok := self leapYear:yr
+    ] ifFalse:[
+	ok := day <= (self daysInMonth:month forYear:yr)
+    ].
+    ((day > 0) and:[ok]) ifTrue:[
+	^ self basicNew dateEncoding:(((yr * 100) + monthIndex) * 100) + day
+    ].
+
+    "this error is triggered if you try to create a date from an
+     invalid year/month/day combination;
+     Such as 29-feb-year, where year is no leap year
+    "
+    self error:'invalid date'
+
+    "
+     Date newDay:8  month:'may' year:1993
+     Date newDay:8  month:5     year:1994
+     Date newDay:29 month:'feb' year:1994
+     Date newDay:29 month:'feb' year:1993
+     Date newDay:28 month:'feb' year:5
+     Date newDay:28 month:'feb' year:95
+    "
+!
+
+newDay:dayInYear year:year
+    "return a new Date, given the year and the day-in-year (starting at 1).
+     ST-80 compatibility"
+
+    |monthAndDay|
+
+    (dayInYear between:1 and:365) ifFalse:[
+	((dayInYear == 366) and:[self leapYear:year]) ifFalse:[
+	    "
+	     this error is triggered, when you try to create a
+	     day from an invalid day-in-year; 
+	     for example, 366 in a non-leap year.
+	     I dont know, if ST-80 wraps to the next year(s) in this case.
+	    "
+	    ^ self error:'invalid date'
+	]
+    ].
+    monthAndDay := self monthAndDayFromDayInYear:dayInYear forYear:year.
+    ^ self day:(monthAndDay at:2) month:(monthAndDay at:1) year:year
+
+    "
+     Date newDay:150 year:1994
+     Date newDay:1 year:1994
+     Date newDay:1 year:1901
+     Date newDay:1 year:1902
+     Date newDay:365 year:1992
+     Date newDay:366 year:1992
+     Date newDay:365 year:1994
+     Date newDay:366 year:1994
+    "
+!
+
+readFrom:aStringOrStream onError:exceptionBlock
+    "return a new Date, reading a printed representation from aStream.
+     Notice, that this is not the storeString format and 
+     is different from the format expected by readFrom:.
+     BUG:
+       This method assumes american format (i.e. month-day-year) instead
+       of the german/french and other day-month-year.
+       There ought to be a nationalized variant of this."
+
+    |str month day year|
+
+    Object errorSignal handle:[:ex |
+	^ exceptionBlock value
+    ] do:[
+	str := aStringOrStream readStream.
+
+	[str peek isLetterOrDigit] whileFalse:[str next].
+	(str peek isDigit) ifTrue:[
+	    day := Integer readFrom:str onError:[^ exceptionBlock value]
+	].
+	[str peek isLetterOrDigit] whileFalse:[str next].
+	(str peek isLetter) ifTrue:[
+	    month := str nextAlphaNumericWord.
+	    day isNil ifTrue:[
+		[str peek isLetterOrDigit] whileFalse:[str next].
+		day := Integer readFrom:str onError:[^ exceptionBlock value].
+	    ]
+	] ifFalse:[
+	    month := self nameOfMonth:day.
+	    day := Integer readFrom:str onError:[^ exceptionBlock value]
+	].
+	[str peek isLetterOrDigit] whileFalse:[str next].
+	year := Integer readFrom:str onError:[^ exceptionBlock value].
+	^ self newDay:day month:month year:year
+    ].
+
+    "
+     Date readFromString:'31 December 1992'  
+     Date readFromString:'December, 5, 1992'  
+     Date readFromString:'December, 5 1992'  
+     Date readFromString:'3-jan-95'           
+     Date readFromString:'12/31/1992'        
+     Date readFromString:'15.4.1992'         -> german; leads to an error
+     Date readFromString:'10.4.1992'         -> german; leads to a wrong date
+     Date readFromString:'10.4.1992' onError:['wrong date']
+    "
+
+    "Created: 16.11.1995 / 22:50:17 / cg"
+!
+
+today
+    "return a date, representing today"
+
+    ^ self fromOSTime:OperatingSystem getTimeParts
+
+    "
+     Date today
+    "
+! !
+
+!Date class methodsFor:'general queries'!
+
+abbreviatedNameOfDay:dayIndex
+    "given a day index (1..7), return the abbreviated name
+     of the day"
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    ^ DayAbbrevs at:dayIndex
+
+    "
+     Date abbreviatedNameOfDay:4
+    "
+!
+
+abbreviatedNameOfMonth:monthIndex
+    "given a month index (1..12), return the abbreviated name
+     of the month"
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    ^ MonthAbbrevs at:monthIndex
+
+    "
+     Date abbreviatedNameOfMonth:11
+     Date abbreviatedNameOfMonth:12
+    "
+!
+
+dateAndTimeNow
+    "return an array containing the date and time of now"
+
+    ^ Time dateAndTimeNow
+
+    "
+     Date dateAndTimeNow
+    "
+!
+
+dayOfWeek:dayName
+    "given the name of a day (either string or symbol),
+     return the day-index (1 for monday; 7 for sunday).
+     Return 0 for invalid day name"
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    ^ DayNames indexOf:dayName
+
+    "
+     Date dayOfWeek:'wednesday'
+    "
+!
+
+daysInMonth:month forYear:yearInteger
+    "given the name of a month and a year, return the number 
+     of days this month has (modified GNU).
+     return 0 if the month name was invalid.
+     For your convenience, month maybe an integer or name-string."
+
+    |monthIndex "{ Class: SmallInteger }"|
+
+    month isInteger ifTrue:[
+	monthIndex := month
+    ] ifFalse:[
+	monthIndex := self indexOfMonth:month
+    ].
+
+    ^ self daysInMonthIndex:monthIndex forYear:yearInteger
+
+    "
+     Date daysInMonth:2 forYear:1980
+     Date daysInMonth:2 forYear:1981
+     Date daysInMonth:'feb' forYear:1981
+    "
+!
+
+daysInYear:yearInteger
+    "return the number of days in a year"
+
+    (self leapYear:yearInteger) ifTrue:[^ 366].
+    ^ 365
+
+    "
+     Date daysInYear:1900  
+     Date daysInYear:1901 
+     Date daysInYear:1904 
+     Date daysInYear:1980 
+     Date daysInYear:1981
+    "
+!
+
+daysUntilMonth:month forYear:yearInteger
+    "given the name of a month and a year, return the number 
+     of days from 1st january to last of prev month of that year.
+     Return 0 if the month name/index is invalid or is january.
+     For your convenience, month maybe an integer or name-string."
+
+    |monthIndex "{ Class: SmallInteger }"
+     sumDays    "{ Class: SmallInteger }" |
+
+    month isInteger ifTrue:[
+	monthIndex := month
+    ] ifFalse:[
+	monthIndex := self indexOfMonth:month
+    ].
+    (monthIndex between:1 and:12) ifFalse:[^ 0].
+
+    sumDays := 0.
+    1 to:monthIndex-1 do:[:m |
+	sumDays := sumDays + (self daysInMonthIndex:m forYear:yearInteger)
+    ].
+    ^ sumDays
+
+    "
+     Date daysUntilMonth:'feb' forYear:1993
+     Date daysUntilMonth:'jan' forYear:1993
+    "
+!
+
+indexOfMonth:aMonthString
+    "given the name of a month (either string or symbol),
+     return the month-index (1 for jan; 12 for december).
+     The given string may be a full or abbreviated name,
+     case is ignored.
+     Return 0 for invalid month name."
+
+    |idx name|
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    name := aMonthString asLowercase.
+    idx := MonthAbbrevs indexOf:name.
+    idx ~~ 0 ifTrue:[^ idx].
+    idx := MonthNames indexOf:name.
+    idx ~~ 0 ifTrue:[^ idx].
+
+    name at:1 put:(name at:1) asUppercase.
+    idx := MonthAbbrevs indexOf:name.
+    idx ~~ 0 ifTrue:[^ idx].
+    idx := MonthNames indexOf:name.
+    idx ~~ 0 ifTrue:[^ idx].
+
+    ^ idx
+
+    "
+     Date indexOfMonth:'jan'
+     Date indexOfMonth:'Jan'
+     Date indexOfMonth:'December'
+    "
+!
+
+isLeapYear:yearInteger
+    "Return true, if a year is a leap year.
+     Obsolete:
+	 Please use the ST-80 compatible #leapYear for new programs, 
+	 since this method will vanish."
+
+    ^ self leapYear:yearInteger
+!
+
+leapYear:yearInteger
+    "return true, if yearInteger is a leap year."
+
+    |y "{ Class: SmallInteger }"|
+
+    y := yearInteger.
+    (y \\ 4 == 0) ifTrue:[
+	(y \\ 100 ~~ 0) ifTrue:[^ true].
+	(y \\ 400 == 0) ifTrue:[^ true]
+    ].
+    ^ false
+
+    "
+     Date leapYear:1992
+     Date leapYear:1994
+     Date leapYear:1900
+     Date leapYear:2000
+    "
+!
+
+monthAndDayFromDayInYear:aDayInYear forYear:yearInteger
+    "given a day-in-year (1..365) return an Array containing the
+     month index and the day-in-month. Return nil if the argument is invalid."
+
+    |restDays daysInMonth|
+
+    restDays := aDayInYear.
+    restDays < 1 ifTrue:[^ nil].
+
+    1 to:12 do:[:m |
+	daysInMonth := self daysInMonthIndex:m forYear:yearInteger.
+	restDays <= daysInMonth ifTrue:[
+	    ^ Array with:m with:restDays
+	].
+	restDays := restDays - daysInMonth 
+    ].
+    restDays > daysInMonth ifTrue:[^ nil].
+    ^ Array with:12 with:restDays
+
+    "
+     Date monthAndDayFromDayInYear:66 forYear:1980
+     Date monthAndDayFromDayInYear:66 forYear:1981
+    "
+!
+
+nameOfDay:dayIndex
+    "given a day index (1..7), return the name of the day" 
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    ^ DayNames at:dayIndex
+
+    "
+     Date nameOfDay:4
+    "
+!
+
+nameOfMonth:monthIndex
+    "given a month index (1..12), return the name of the month"
+
+    EnvironmentChange ifTrue:[
+	self initNames
+    ].
+    ^ MonthNames at:monthIndex
+
+    "
+     Date nameOfMonth:11
+     Date nameOfMonth:12
+     Date nameOfMonth:4
+    "
+!
+
+yearAsDays: yearInteger
+    "Returns the number of days since Jan 1, 1901. (GNU)
+     to the first Jan of the year, yearInteger.
+     For 1901 this is zero, for 1902 its 365.
+     Defined for years >= 1901"
+
+    |y "{ Class: SmallInteger }"|
+
+    y := yearInteger - 1900.
+    y := y - 1.
+    ^ (y * 365)
+	+ (y // 4)
+	- (y // 100)
+	+ ((y + 300) // 400)
+
+    "
+     Date yearAsDays:1901 
+     Date yearAsDays:1902   
+     Date yearAsDays:1903   
+     Date yearAsDays:1904    
+     Date yearAsDays:1905     
+     Date yearAsDays:1994   
+     (Date yearAsDays:2001) - (Date yearAsDays:2000)   
+    "
+! !
+
+!Date class methodsFor:'handling language changes'!
+
+initialize
+    "check for case where Resource-classes are absent"
+    ResourcePack isNil ifTrue:[
+	self initNames
+    ] ifFalse:[
+	Smalltalk addDependent:self.
+	EnvironmentChange := true
+    ]
+!
+
+update:something
+    ((something == #Language) or:[something == #LanguageTerritory]) ifTrue:[
+	"just remember change for next access"
+	EnvironmentChange := true
+    ]
+! !
+
 !Date class methodsFor:'private'!
 
+daysInMonthIndex: monthIndex forYear: yearInteger
+    "return the number of days in month monthIndex of
+     year yearInteger (modified GNU).
+     Return 0 for invalid month index.
+     This is the internal version of daysInMonth:forYear:"
+
+    |days|
+
+    (monthIndex between:1 and:12) ifFalse:[^ 0].
+
+    days := #(31 28 31           "Jan Feb Mar"
+	      30 31 30           "Apr May Jun"
+	      31 31 30           "Jul Aug Sep"
+	      31 30 31           "Oct Nov Dec"
+	     ) at: monthIndex.
+
+    (monthIndex == 2) ifTrue:[
+	(self leapYear:yearInteger) ifTrue:[
+	    ^ days + 1
+	]
+    ].
+    ^ days
+
+    "
+     Date daysInMonthIndex:2 forYear:1994
+     Date daysInMonthIndex:2 forYear:1980
+     Date daysInMonthIndex:2 forYear:1981
+    "
+!
+
 initNames
     "read the language specific names"
 
@@ -133,520 +642,6 @@
     EnvironmentChange := false
 
     "Date initNames"
-!
-
-daysInMonthIndex: monthIndex forYear: yearInteger
-    "return the number of days in month monthIndex of
-     year yearInteger (modified GNU).
-     Return 0 for invalid month index.
-     This is the internal version of daysInMonth:forYear:"
-
-    |days|
-
-    (monthIndex between:1 and:12) ifFalse:[^ 0].
-
-    days := #(31 28 31           "Jan Feb Mar"
-	      30 31 30           "Apr May Jun"
-	      31 31 30           "Jul Aug Sep"
-	      31 30 31           "Oct Nov Dec"
-	     ) at: monthIndex.
-
-    (monthIndex == 2) ifTrue:[
-	(self leapYear:yearInteger) ifTrue:[
-	    ^ days + 1
-	]
-    ].
-    ^ days
-
-    "
-     Date daysInMonthIndex:2 forYear:1994
-     Date daysInMonthIndex:2 forYear:1980
-     Date daysInMonthIndex:2 forYear:1981
-    "
-! !
-
-!Date class methodsFor:'handling language changes'!
-
-initialize
-    "check for case where Resource-classes are absent"
-    ResourcePack isNil ifTrue:[
-	self initNames
-    ] ifFalse:[
-	Smalltalk addDependent:self.
-	EnvironmentChange := true
-    ]
-!
-
-update:something
-    ((something == #Language) or:[something == #LanguageTerritory]) ifTrue:[
-	"just remember change for next access"
-	EnvironmentChange := true
-    ]
-! !
-
-!Date class methodsFor:'general queries'!
-
-dateAndTimeNow
-    "return an array containing the date and time of now"
-
-    ^ Time dateAndTimeNow
-
-    "
-     Date dateAndTimeNow
-    "
-!
-
-dayOfWeek:dayName
-    "given the name of a day (either string or symbol),
-     return the day-index (1 for monday; 7 for sunday).
-     Return 0 for invalid day name"
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    ^ DayNames indexOf:dayName
-
-    "
-     Date dayOfWeek:'wednesday'
-    "
-!
-
-nameOfDay:dayIndex
-    "given a day index (1..7), return the name of the day" 
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    ^ DayNames at:dayIndex
-
-    "
-     Date nameOfDay:4
-    "
-!
-
-abbreviatedNameOfDay:dayIndex
-    "given a day index (1..7), return the abbreviated name
-     of the day"
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    ^ DayAbbrevs at:dayIndex
-
-    "
-     Date abbreviatedNameOfDay:4
-    "
-!
-
-indexOfMonth:aMonthString
-    "given the name of a month (either string or symbol),
-     return the month-index (1 for jan; 12 for december).
-     The given string may be a full or abbreviated name,
-     case is ignored.
-     Return 0 for invalid month name."
-
-    |idx name|
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    name := aMonthString asLowercase.
-    idx := MonthAbbrevs indexOf:name.
-    idx ~~ 0 ifTrue:[^ idx].
-    idx := MonthNames indexOf:name.
-    idx ~~ 0 ifTrue:[^ idx].
-
-    name at:1 put:(name at:1) asUppercase.
-    idx := MonthAbbrevs indexOf:name.
-    idx ~~ 0 ifTrue:[^ idx].
-    idx := MonthNames indexOf:name.
-    idx ~~ 0 ifTrue:[^ idx].
-
-    ^ idx
-
-    "
-     Date indexOfMonth:'jan'
-     Date indexOfMonth:'Jan'
-     Date indexOfMonth:'December'
-    "
-!
-
-nameOfMonth:monthIndex
-    "given a month index (1..12), return the name of the month"
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    ^ MonthNames at:monthIndex
-
-    "
-     Date nameOfMonth:11
-     Date nameOfMonth:12
-     Date nameOfMonth:4
-    "
-!
-
-abbreviatedNameOfMonth:monthIndex
-    "given a month index (1..12), return the abbreviated name
-     of the month"
-
-    EnvironmentChange ifTrue:[
-	self initNames
-    ].
-    ^ MonthAbbrevs at:monthIndex
-
-    "
-     Date abbreviatedNameOfMonth:11
-     Date abbreviatedNameOfMonth:12
-    "
-!
-
-daysInMonth:month forYear:yearInteger
-    "given the name of a month and a year, return the number 
-     of days this month has (modified GNU).
-     return 0 if the month name was invalid.
-     For your convenience, month maybe an integer or name-string."
-
-    |monthIndex "{ Class: SmallInteger }"|
-
-    month isInteger ifTrue:[
-	monthIndex := month
-    ] ifFalse:[
-	monthIndex := self indexOfMonth:month
-    ].
-
-    ^ self daysInMonthIndex:monthIndex forYear:yearInteger
-
-    "
-     Date daysInMonth:2 forYear:1980
-     Date daysInMonth:2 forYear:1981
-     Date daysInMonth:'feb' forYear:1981
-    "
-!
-
-daysUntilMonth:month forYear:yearInteger
-    "given the name of a month and a year, return the number 
-     of days from 1st january to last of prev month of that year.
-     Return 0 if the month name/index is invalid or is january.
-     For your convenience, month maybe an integer or name-string."
-
-    |monthIndex "{ Class: SmallInteger }"
-     sumDays    "{ Class: SmallInteger }" |
-
-    month isInteger ifTrue:[
-	monthIndex := month
-    ] ifFalse:[
-	monthIndex := self indexOfMonth:month
-    ].
-    (monthIndex between:1 and:12) ifFalse:[^ 0].
-
-    sumDays := 0.
-    1 to:monthIndex-1 do:[:m |
-	sumDays := sumDays + (self daysInMonthIndex:m forYear:yearInteger)
-    ].
-    ^ sumDays
-
-    "
-     Date daysUntilMonth:'feb' forYear:1993
-     Date daysUntilMonth:'jan' forYear:1993
-    "
-!
-
-monthAndDayFromDayInYear:aDayInYear forYear:yearInteger
-    "given a day-in-year (1..365) return an Array containing the
-     month index and the day-in-month. Return nil if the argument is invalid."
-
-    |restDays daysInMonth|
-
-    restDays := aDayInYear.
-    restDays < 1 ifTrue:[^ nil].
-
-    1 to:12 do:[:m |
-	daysInMonth := self daysInMonthIndex:m forYear:yearInteger.
-	restDays <= daysInMonth ifTrue:[
-	    ^ Array with:m with:restDays
-	].
-	restDays := restDays - daysInMonth 
-    ].
-    restDays > daysInMonth ifTrue:[^ nil].
-    ^ Array with:12 with:restDays
-
-    "
-     Date monthAndDayFromDayInYear:66 forYear:1980
-     Date monthAndDayFromDayInYear:66 forYear:1981
-    "
-! 
-
-daysInYear:yearInteger
-    "return the number of days in a year"
-
-    (self leapYear:yearInteger) ifTrue:[^ 366].
-    ^ 365
-
-    "
-     Date daysInYear:1900  
-     Date daysInYear:1901 
-     Date daysInYear:1904 
-     Date daysInYear:1980 
-     Date daysInYear:1981
-    "
-!
-
-yearAsDays: yearInteger
-    "Returns the number of days since Jan 1, 1901. (GNU)
-     to the first Jan of the year, yearInteger.
-     For 1901 this is zero, for 1902 its 365.
-     Defined for years >= 1901"
-
-    |y "{ Class: SmallInteger }"|
-
-    y := yearInteger - 1900.
-    y := y - 1.
-    ^ (y * 365)
-	+ (y // 4)
-	- (y // 100)
-	+ ((y + 300) // 400)
-
-    "
-     Date yearAsDays:1901 
-     Date yearAsDays:1902   
-     Date yearAsDays:1903   
-     Date yearAsDays:1904    
-     Date yearAsDays:1905     
-     Date yearAsDays:1994   
-     (Date yearAsDays:2001) - (Date yearAsDays:2000)   
-    "
-!
-
-leapYear:yearInteger
-    "return true, if yearInteger is a leap year."
-
-    |y "{ Class: SmallInteger }"|
-
-    y := yearInteger.
-    (y \\ 4 == 0) ifTrue:[
-	(y \\ 100 ~~ 0) ifTrue:[^ true].
-	(y \\ 400 == 0) ifTrue:[^ true]
-    ].
-    ^ false
-
-    "
-     Date leapYear:1992
-     Date leapYear:1994
-     Date leapYear:1900
-     Date leapYear:2000
-    "
-!
-
-isLeapYear:yearInteger
-    "Return true, if a year is a leap year.
-     Obsolete:
-	 Please use the ST-80 compatible #leapYear for new programs, 
-	 since this method will vanish."
-
-    ^ self leapYear:yearInteger
-! !
-
-!Date class methodsFor:'instance creation'!
-
-fromOSTime:osTime
-    "return a date, representing the date given by the operatingSystem time.
-     This somewhat clumsy implementation hides the OS's date representation
-     (i.e. makes this class independent of what the OS starts its time values with).
-     Dont use this method, the osTime representation is totally unportable."
-
-    ^ self basicNew fromOSTime:osTime
-
-    "
-     Date fromOSTime:#(0 0)      -> on UNIX: this should return 1st Jan 1970
-				    thats where Unix time starts
-				    On other systems, it may be something different.
-
-     Date fromOSTime:#(86400 0)  -> on UNIX: the day after
-    "
-!
-
-today
-    "return a date, representing today"
-
-    ^ self fromOSTime:OperatingSystem getTimeParts
-
-    "
-     Date today
-    "
-!
-
-fromDays:dayCount
-    "return a new Date, given the day-number starting with 0 at 1.Jan 1901;
-     (i.e. 'Date fromDays:0' returns 1st Jan. 1901).
-     Date asDays is the reverse operation.
-     for GNU/ST-80 compatibility"
-
-    |yr rest d|
-
-    "approx. year"
-    yr := (dayCount // 366) + 1901.
-    rest := dayCount - (self yearAsDays:yr) + 1. "+1 for ST-80 compatibility"
-    d := self daysInYear:yr.
-    (rest > d) ifTrue:[
-	"adjust"
-	yr := yr + 1.
-	rest := rest - d.
-    ].
-
-    ^ self day:rest year:yr
-
-    "
-     Date fromDays:0     -> 1 jan 1901
-     Date fromDays:365   -> 1 jan 1902
-     Date fromDays:730   -> 1 jan 1903
-     Date fromDays:1095  -> 1 jan 1903
-     Date fromDays:1460  ->31 dec 1904 since 1904 was a leap year
-    "
-!
-
-day:dayInYear year:year
-    "return a new Date, given the year and the day-in-year (starting at 1).
-     Obsolete:
-	use newDay:year: for ST-80 compatibility"
-
-    ^ self newDay:dayInYear year:year
-!
-
-newDay:dayInYear year:year
-    "return a new Date, given the year and the day-in-year (starting at 1).
-     ST-80 compatibility"
-
-    |monthAndDay|
-
-    (dayInYear between:1 and:365) ifFalse:[
-	((dayInYear == 366) and:[self leapYear:year]) ifFalse:[
-	    "
-	     this error is triggered, when you try to create a
-	     day from an invalid day-in-year; 
-	     for example, 366 in a non-leap year.
-	     I dont know, if ST-80 wraps to the next year(s) in this case.
-	    "
-	    ^ self error:'invalid date'
-	]
-    ].
-    monthAndDay := self monthAndDayFromDayInYear:dayInYear forYear:year.
-    ^ self day:(monthAndDay at:2) month:(monthAndDay at:1) year:year
-
-    "
-     Date newDay:150 year:1994
-     Date newDay:1 year:1994
-     Date newDay:1 year:1901
-     Date newDay:1 year:1902
-     Date newDay:365 year:1992
-     Date newDay:366 year:1992
-     Date newDay:365 year:1994
-     Date newDay:366 year:1994
-    "
-!
-
-day:day month:month year:year
-    "return a new Date, given the day, month and year.
-     Obsolete:
-	use newDay:month:year: for ST-80 compatibility"
-
-    ^ self newDay:day month:month year:year
-!
-
-newDay:day month:month year:year
-    "return a new Date, given the day, month and year.
-     For your convenience, month may be either an integer 
-     or the months name as a string. 
-     Year may be the actual year (such as 1890, 2001) or the number 
-     of years since 1900 (which is rubbish ST-80 compatibility: 
-     it will be totally useless in a few years ...).
-     You better not use this short-year feature in your programs."
-
-    |monthIndex ok yr|
-
-    yr := year.
-    yr < 100 ifTrue:[
-	yr := yr + 1900.
-    ].
-
-    month isInteger ifTrue:[
-	monthIndex := month
-    ] ifFalse:[
-	monthIndex := self indexOfMonth:month
-    ].
-    (monthIndex == 2 and:[day == 29]) ifTrue:[
-	ok := self leapYear:yr
-    ] ifFalse:[
-	ok := day <= (self daysInMonth:month forYear:yr)
-    ].
-    ((day > 0) and:[ok]) ifTrue:[
-	^ self basicNew dateEncoding:(((yr * 100) + monthIndex) * 100) + day
-    ].
-
-    "this error is triggered if you try to create a date from an
-     invalid year/month/day combination;
-     Such as 29-feb-year, where year is no leap year
-    "
-    self error:'invalid date'
-
-    "
-     Date newDay:8  month:'may' year:1993
-     Date newDay:8  month:5     year:1994
-     Date newDay:29 month:'feb' year:1994
-     Date newDay:29 month:'feb' year:1993
-     Date newDay:28 month:'feb' year:5
-     Date newDay:28 month:'feb' year:95
-    "
-!
-
-readFrom:aStringOrStream onError:exceptionBlock
-    "return a new Date, reading a printed representation from aStream.
-     Notice, that this is not the storeString format and 
-     is different from the format expected by readFrom:.
-     BUG:
-       This method assumes american format (i.e. month-day-year) instead
-       of the german/french and other day-month-year.
-       There ought to be a nationalized variant of this."
-
-    |str month day year|
-
-    Object errorSignal handle:[:ex |
-	^ exceptionBlock value
-    ] do:[
-	str := aStringOrStream readStream.
-
-	[str peek isLetterOrDigit] whileFalse:[str next].
-	(str peek isDigit) ifTrue:[
-	    day := Integer readFrom:str onError:[^ exceptionBlock value]
-	].
-	[str peek isLetterOrDigit] whileFalse:[str next].
-	(str peek isLetter) ifTrue:[
-	    month := str nextAlphaNumericWord.
-	    day isNil ifTrue:[
-		[str peek isLetterOrDigit] whileFalse:[str next].
-		day := Integer readFrom:str onError:[^ exceptionBlock value].
-	    ]
-	] ifFalse:[
-	    month := self nameOfMonth:day.
-	    day := Integer readFrom:str onError:[^ exceptionBlock value]
-	].
-	[str peek isLetterOrDigit] whileFalse:[str next].
-	year := Integer readFrom:str onError:[^ exceptionBlock value].
-	^ self newDay:day month:month year:year
-    ].
-
-    "
-     Date readFromString:'31 December 1992'  
-     Date readFromString:'December, 5, 1992'  
-     Date readFromString:'December, 5 1992'  
-     Date readFromString:'3-jan-95'           
-     Date readFromString:'12/31/1992'        
-     Date readFromString:'15.4.1992'         -> german; leads to an error
-     Date readFromString:'10.4.1992'         -> german; leads to a wrong date
-     Date readFromString:'10.4.1992' onError:['wrong date']
-    "
-
-    "Created: 16.11.1995 / 22:50:17 / cg"
 ! !
 
 !Date class methodsFor:'private encoding'!
@@ -658,168 +653,31 @@
     ^ (((y * 100) + m) * 100) + d
 ! !
 
-!Date methodsFor:'private accessing'!
-
-dateEncoding
-    "the internal encoding is stricktly private, 
-     and should not be used outside."
-
-    ^ dateEncoding
-!
-
-dateEncoding:anInteger
-    "the internal encoding is stricktly private, 
-     and should not be used outside."
-
-    dateEncoding := anInteger
-!
-
-fromOSTime:osTime
-    "set my dateEncoding from an OS time.
-     This somewhat clumsy implementation hides the OS's date representation
-     (i.e. makes this class independent of what the OS starts its time values with).
-     Dont use this method, the osTime representation is totally unportable."
+!Date methodsFor:'accessing'!
 
-    OperatingSystem computeDatePartsOf:osTime 
-				   for:[:year :month :day |
-	dateEncoding := (((year * 100) + month) * 100) + day
-    ]
-! !
-
-!Date methodsFor:'arithmetic'!
+abbreviatedDayName
+    "return the short week-day of the receiver as a string.
+     The returned string depends on the language setting.
+     Expect things like 'mon', 'tue' ..."
 
-plusDays:days
-    "return a new date representing 'days' after the receiver.
-     The argument should be some kind of integer.
-     Obsolete:
-	 Please dont use this method since it will vanish.
-	 Use #addDays: instead for ST-80 compatibility."
-
-    ^ self addDays:days
-!
-
-addDays:days
-    "return a new date representing 'days' after the receiver.
-     The argument should be some kind of integer.
-     For ST-80 compatibility."
-
-    ^ self class fromDays:(self asDays + days)
+    ^ self class abbreviatedNameOfDay:(self dayInWeek)
 
     "
-     Date today addDays:7
-    "
-!
-
-minusDays:days
-    "return a new date representing 'days' before the receiver.
-     The argument should be some kind of integer.
-     Obsolete:
-	 Please dont use this method since it will vanish.
-	 Use #subtractDays: instead for ST-80 compatibility."
-
-    ^ self subtractDays:days
-!
-
-subtractDays:days
-    "return a new date representing 'days' before the receiver.
-     The argument should be some kind of integer.
-     For ST-80 compatibility"
-
-    ^ self class fromDays:(self asDays - days)
-
-    "
-     Date today subtractDays:7
+     Date today abbreviatedDayName
+     (Date day:15 month:4 year:1959) abbreviatedDayName
     "
 !
 
-subtractDate:aDate
-    "return the number of days between the receiver and aDate"
-
-    ^ self asDays - aDate asDays
-
-    "
-    (Date day:1 month:1 year:1995) subtractDate:(Date day:24 month:12 year:1994)
-    (Date day:1 month:3 year:1992) subtractDate:(Date day:1 month:2 year:1992)
-    (Date day:1 month:3 year:1994) subtractDate:(Date day:1 month:2 year:1994)
-    "
-!
-
-daysUntil:aDate
-    "return the number of days between the receiver and the argument,
-     aDate, whuch should be some kind of date"
-
-    ^ aDate asDays - self asDays
+abbreviatedMonthName
+    "return the month of the receiver as a string.
+     The returned string depends on the language setting.
+     Expect things like 'jan', 'feb' ..."
 
-    "
-     (Date day:24 month:12 year:1994) daysUntil:(Date day:1 month:1 year:1995)
-     (Date day:1 month:2 year:1992) daysUntil:(Date day:1 month:3 year:1992)
-     (Date day:1 month:2 year:1994) daysUntil:(Date day:1 month:3 year:1994)
-    
-     |delta|
-     delta := Date today
-		daysUntil:(Date day:25 month:12 year:Date today year).
-     Transcript show:'still ';
-		show:delta ;
-		showCr:' days till xmas'
-    "
-! !
-    
-!Date methodsFor:'accessing'!
-
-day
-    "return the day (1..31) of the receiver"
-
-    ^ dateEncoding \\ 100
+    ^ self class abbreviatedNameOfMonth:(self month)
 
     "
-     Date today day
-    "
-!
-
-month
-    "return the month (1..12) of the receiver"
-
-    ^ (dateEncoding // 100) \\ 100
-
-    "
-     Date today month
-    "
-!
-
-year
-    "return the year (1..12) of the receiver"
-
-    ^ dateEncoding // (100*100)
-
-    "
-     Date today year
-    "
-!
-
-leap
-    "return true, if the receivers year is a leap year"
-
-    ^ Date leapYear:(self year)
-
-    "
-     Date today leap
-     (Date day:1 month:1 year:1992) leap
-    "
-!
-
-dayCount
-    "return the number of days since 1st. Jan. 1901;
-     starting with 0 for this date.
-     Date>>fromDays: is the reverse operation.
-     Obsolete:
-	 please use asDays for ST-80 compatibility"
-
-    ^ self asDays.
-
-    "
-     (Date day:1 month:1 year:1901) dayCount
-     Date fromDays:(Date day:1 month:1 year:1994) dayCount
-     Date today dayCount
+     Date today abbreviatedMonthName
+     (Date day:15 month:4 year:1959) abbreviatedMonthName
     "
 !
 
@@ -857,7 +715,55 @@
      (Date day: 1 month: 1 year: 1901) asSeconds
      (Date today addDays:7) asSeconds - Date today asSeconds
     "  
-! 
+!
+
+day
+    "return the day (1..31) of the receiver"
+
+    ^ dateEncoding \\ 100
+
+    "
+     Date today day
+    "
+!
+
+dayCount
+    "return the number of days since 1st. Jan. 1901;
+     starting with 0 for this date.
+     Date>>fromDays: is the reverse operation.
+     Obsolete:
+	 please use asDays for ST-80 compatibility"
+
+    ^ self asDays.
+
+    "
+     (Date day:1 month:1 year:1901) dayCount
+     Date fromDays:(Date day:1 month:1 year:1994) dayCount
+     Date today dayCount
+    "
+!
+
+dayInWeek
+    "return the week-day of the receiver - 1 for monday, 7 for sunday"
+
+    ^ (1 "know, that 1st Jan 1901 was a tuesday"
+      + self asDays) \\ 7 + 1
+
+    "
+     Date today dayInWeek
+     (Date day:15 month:4 year:1959) dayInWeek
+    "
+!
+
+dayName
+    "return the week-day of the receiver as a string.
+     The returned string depends on the language setting.
+     Expect things like 'monday', 'tuesday' ...
+     Obsolete:
+	use #weekday for ST-80 compatibility"
+
+    ^ self weekday
+!
 
 dayOfMonth
     "Answer the day of the month represented by me.
@@ -900,52 +806,24 @@
     "
 !
 
-dayInWeek
-    "return the week-day of the receiver - 1 for monday, 7 for sunday"
+leap
+    "return true, if the receivers year is a leap year"
 
-    ^ (1 "know, that 1st Jan 1901 was a tuesday"
-      + self asDays) \\ 7 + 1
+    ^ Date leapYear:(self year)
 
     "
-     Date today dayInWeek
-     (Date day:15 month:4 year:1959) dayInWeek
+     Date today leap
+     (Date day:1 month:1 year:1992) leap
     "
 !
 
-dayName
-    "return the week-day of the receiver as a string.
-     The returned string depends on the language setting.
-     Expect things like 'monday', 'tuesday' ...
-     Obsolete:
-	use #weekday for ST-80 compatibility"
+month
+    "return the month (1..12) of the receiver"
 
-    ^ self weekday
-!
-
-weekday
-    "return the week-day of the receiver as a string.
-     The returned string depends on the language setting.
-     Expect things like 'monday', 'tuesday' ...
-     For ST-80 compatibility"
-
-    ^ self class nameOfDay:(self dayInWeek)
+    ^ (dateEncoding // 100) \\ 100
 
     "
-     Date today weekday
-     (Date day:15 month:4 year:1959) weekday
-    "
-!
-
-abbreviatedDayName
-    "return the short week-day of the receiver as a string.
-     The returned string depends on the language setting.
-     Expect things like 'mon', 'tue' ..."
-
-    ^ self class abbreviatedNameOfDay:(self dayInWeek)
-
-    "
-     Date today abbreviatedDayName
-     (Date day:15 month:4 year:1959) abbreviatedDayName
+     Date today month
     "
 !
 
@@ -969,16 +847,105 @@
     "
 !
 
-abbreviatedMonthName
-    "return the month of the receiver as a string.
+weekday
+    "return the week-day of the receiver as a string.
      The returned string depends on the language setting.
-     Expect things like 'jan', 'feb' ..."
+     Expect things like 'monday', 'tuesday' ...
+     For ST-80 compatibility"
+
+    ^ self class nameOfDay:(self dayInWeek)
+
+    "
+     Date today weekday
+     (Date day:15 month:4 year:1959) weekday
+    "
+!
+
+year
+    "return the year (1..12) of the receiver"
+
+    ^ dateEncoding // (100*100)
 
-    ^ self class abbreviatedNameOfMonth:(self month)
+    "
+     Date today year
+    "
+! !
+
+!Date methodsFor:'arithmetic'!
+
+addDays:days
+    "return a new date representing 'days' after the receiver.
+     The argument should be some kind of integer.
+     For ST-80 compatibility."
+
+    ^ self class fromDays:(self asDays + days)
+
+    "
+     Date today addDays:7
+    "
+!
+
+daysUntil:aDate
+    "return the number of days between the receiver and the argument,
+     aDate, whuch should be some kind of date"
+
+    ^ aDate asDays - self asDays
 
     "
-     Date today abbreviatedMonthName
-     (Date day:15 month:4 year:1959) abbreviatedMonthName
+     (Date day:24 month:12 year:1994) daysUntil:(Date day:1 month:1 year:1995)
+     (Date day:1 month:2 year:1992) daysUntil:(Date day:1 month:3 year:1992)
+     (Date day:1 month:2 year:1994) daysUntil:(Date day:1 month:3 year:1994)
+    
+     |delta|
+     delta := Date today
+		daysUntil:(Date day:25 month:12 year:Date today year).
+     Transcript show:'still ';
+		show:delta ;
+		showCr:' days till xmas'
+    "
+!
+
+minusDays:days
+    "return a new date representing 'days' before the receiver.
+     The argument should be some kind of integer.
+     Obsolete:
+	 Please dont use this method since it will vanish.
+	 Use #subtractDays: instead for ST-80 compatibility."
+
+    ^ self subtractDays:days
+!
+
+plusDays:days
+    "return a new date representing 'days' after the receiver.
+     The argument should be some kind of integer.
+     Obsolete:
+	 Please dont use this method since it will vanish.
+	 Use #addDays: instead for ST-80 compatibility."
+
+    ^ self addDays:days
+!
+
+subtractDate:aDate
+    "return the number of days between the receiver and aDate"
+
+    ^ self asDays - aDate asDays
+
+    "
+    (Date day:1 month:1 year:1995) subtractDate:(Date day:24 month:12 year:1994)
+    (Date day:1 month:3 year:1992) subtractDate:(Date day:1 month:2 year:1992)
+    (Date day:1 month:3 year:1994) subtractDate:(Date day:1 month:2 year:1994)
+    "
+!
+
+subtractDays:days
+    "return a new date representing 'days' before the receiver.
+     The argument should be some kind of integer.
+     For ST-80 compatibility"
+
+    ^ self class fromDays:(self asDays - days)
+
+    "
+     Date today subtractDays:7
     "
 ! !
 
@@ -1003,25 +970,6 @@
     "Date today < (Date day:24 month:12 year:1900)"
 !
 
-> aDate
-    "return true, if the date represented by the receiver
-     is after the argument, aDate"
-
-    (aDate isMemberOf:Date) ifTrue:[
-	^ dateEncoding > aDate dateEncoding
-    ].
-
-    "the argument must understand year, month and day to be
-     comparable, whatever it is"
-
-    ^ dateEncoding > (Date encodeYear:aDate year
-				month:aDate month
-				  day:aDate day)
-
-    "Date today > (Date day:24 month:12 year:2000)"
-    "Date today > (Date day:24 month:12 year:1900)"
-!
-
 = aDate
     "return true, if the date represented by the receiver
      is the same as the one represented by argument, aDate"
@@ -1041,6 +989,25 @@
     "Date today = ((Date today plusDays:7) minusDays:7)"
 !
 
+> aDate
+    "return true, if the date represented by the receiver
+     is after the argument, aDate"
+
+    (aDate isMemberOf:Date) ifTrue:[
+	^ dateEncoding > aDate dateEncoding
+    ].
+
+    "the argument must understand year, month and day to be
+     comparable, whatever it is"
+
+    ^ dateEncoding > (Date encodeYear:aDate year
+				month:aDate month
+				  day:aDate day)
+
+    "Date today > (Date day:24 month:12 year:2000)"
+    "Date today > (Date day:24 month:12 year:1900)"
+!
+
 hash
     "return an integer useful for hashing on dates"
 
@@ -1049,37 +1016,6 @@
 
 !Date methodsFor:'printing & storing'!
 
-storeOn:aStream
-    "append a representation to aStream, from which the receiver
-     can be reconstructed"
-
-    aStream nextPutAll:'('; nextPutAll:'Date day:'.
-    self day printOn:aStream.
-    aStream nextPutAll:' month:'.
-    self month printOn:aStream.
-    aStream nextPutAll:' year:'.
-    self year printOn:aStream.
-    aStream nextPutAll:')'
-
-    "
-     Date today storeOn:Transcript
-     Date today storeString
-    "
-!
-
-printOn:aStream
-    "append a printed representation of the receiver to aStream"
-
-    self printFormat:#(1 2 3 $- 2 1) on:aStream
-
-    "
-     Date today printOn:Transcript
-     Date today printNL
-    "
-
-    "Modified: 27.8.1995 / 01:01:49 / claus"
-!
-
 printFormat:aFormatArray
     "return a string containing a printed representation of the receiver.
      The formatArray argument consists of 6 or 7 integers which control
@@ -1199,4 +1135,70 @@
      Date today printFormat:#(1 2 3 $- 2 1) on:Transcript. Transcript cr.
      Date today printFormat:#(1 2 3 $- 4 1) on:Transcript. Transcript cr.
     "
+!
+
+printOn:aStream
+    "append a printed representation of the receiver to aStream"
+
+    self printFormat:#(1 2 3 $- 2 1) on:aStream
+
+    "
+     Date today printOn:Transcript
+     Date today printNL
+    "
+
+    "Modified: 27.8.1995 / 01:01:49 / claus"
+!
+
+storeOn:aStream
+    "append a representation to aStream, from which the receiver
+     can be reconstructed"
+
+    aStream nextPutAll:'('; nextPutAll:'Date day:'.
+    self day printOn:aStream.
+    aStream nextPutAll:' month:'.
+    self month printOn:aStream.
+    aStream nextPutAll:' year:'.
+    self year printOn:aStream.
+    aStream nextPutAll:')'
+
+    "
+     Date today storeOn:Transcript
+     Date today storeString
+    "
 ! !
+
+!Date methodsFor:'private accessing'!
+
+dateEncoding
+    "the internal encoding is stricktly private, 
+     and should not be used outside."
+
+    ^ dateEncoding
+!
+
+dateEncoding:anInteger
+    "the internal encoding is stricktly private, 
+     and should not be used outside."
+
+    dateEncoding := anInteger
+!
+
+fromOSTime:osTime
+    "set my dateEncoding from an OS time.
+     This somewhat clumsy implementation hides the OS's date representation
+     (i.e. makes this class independent of what the OS starts its time values with).
+     Dont use this method, the osTime representation is totally unportable."
+
+    OperatingSystem computeDatePartsOf:osTime 
+				   for:[:year :month :day |
+	dateEncoding := (((year * 100) + month) * 100) + day
+    ]
+! !
+
+!Date class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.29 1995-12-07 21:32:16 cg Exp $'
+! !
+Date initialize!