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