"
COPYRIGHT (c) 1989 by Claus Gittinger
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.
----------------------------------------------------------------
For code marked as (GNU) the following applies:
Copyright (C) 1988, 1989 Free Software Foundation, Inc.
Written by Steve Byrne.
This file is part of GNU Smalltalk.
GNU Smalltalk is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later version.
GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU Smalltalk; see the file LICENSE. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
----------------------------------------------------------------
"
AbsoluteTime subclass:#Date
instanceVariableNames:''
classVariableNames:'DayNames MonthNames DayAbbrevs MonthAbbrevs
EnvironmentChange'
poolDictionaries:''
category:'Magnitude-General'
!
Date comment:'
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
$Header: /cvs/stx/stx/libbasic/Date.st,v 1.6 1994-01-08 16:12:00 claus Exp $
written Spring 89 by claus
'!
!Date class methodsFor:'private'!
initNames
"read the language specific names"
|resources|
resources := ResourcePack for:self.
DayNames := resources array:#('monday'
'tuesday'
'wednesday'
'thursday'
'friday'
'saturday'
'sunday').
DayAbbrevs := resources array:#('mon'
'tue'
'wed'
'thu'
'fri'
'sat'
'sun').
MonthNames := resources array:#('january'
'february'
'march'
'april'
'may'
'june'
'july'
'august'
'september'
'october'
'november'
'december').
MonthAbbrevs := resources array:#('jan'
'feb'
'mar'
'apr'
'may'
'jun'
'jul'
'aug'
'sep'
'oct'
'nov'
'dec').
EnvironmentChange := false
"Date initNames"
! !
!Date class methodsFor:'handling language changes'!
initialize
super initialize.
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'!
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'"
!
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.
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'"
!
nameOfDay:dayIndex
"given a day index (1..7), return the name of the day
as a symbol"
EnvironmentChange ifTrue:[
self initNames
].
^ (DayNames at:dayIndex) asSymbol
"Date nameOfDay:4"
!
nameOfMonth:monthIndex
"given a month index (1..12), return the name of the month
as a symbol"
EnvironmentChange ifTrue:[
self initNames
].
^ (MonthNames at:monthIndex) asSymbol
"Date nameOfMonth:11"
"Date nameOfMonth:12"
"Date nameOfMonth:4"
!
abbreviatedNameOfDay:dayIndex
"given a day index (1..7), return the abbreviated name
of the day as a symbol"
EnvironmentChange ifTrue:[
self initNames
].
^ (DayAbbrevs at:dayIndex) asSymbol
!
abbreviatedNameOfMonth:monthIndex
"given a month index (1..12), return the abbreviated name
of the month as a symbol"
EnvironmentChange ifTrue:[
self initNames
].
^ (MonthAbbrevs at:monthIndex) asSymbol
!
daysInMonth:monthName forYear:yearInteger
"given the name of a minth and a year, return the number
of days this month has (modified GNU).
return 0 if the month name was invalid."
|monthIndex|
monthIndex := self indexOfMonth:monthName.
(monthIndex == 0) ifTrue:[
^ 0
].
^ self daysInMonthIndex:monthIndex forYear:yearInteger
"Date daysInMonth:2 forYear:1980"
"Date daysInMonth:2 forYear:1981"
!
daysUntilMonth:monthName forYear:yearInteger
"given the name of a month and a year, return the number
of days from 1st of january to last of prev month.
return 0 if the month name was invalid."
|monthIndex sumDays|
monthIndex := self indexOfMonth:monthName.
(monthIndex == 0) ifTrue:[
^ 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"
!
daysInYear:yearInteger
"return the number of days in a year"
(self isLeapYear:yearInteger) ifTrue:[^ 366].
^ 365
"Date daysInYear:1980"
"Date daysInYear:1981"
!
yearAsDays: yearInteger
"Returns the number of days since Jan 1, 1901. (GNU)"
|y|
y := yearInteger - 1900.
^ (y - 1) * 365
+ (y // 4)
- (y // 100)
+ (y // 400)
!
isLeapYear:yearInteger
"return true, if a year is a leap year"
(yearInteger \\ 4 == 0) ifTrue:[
(yearInteger \\ 100 ~~ 0) ifTrue:[^ true].
(yearInteger \\ 400 == 0) ifTrue:[^ true]
].
^ false
!
daysInMonthIndex: monthIndex forYear: yearInteger
"return the number of days in month monthIndex of
year yearInteger (GNU)"
|days|
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 isLeapYear:yearInteger) ifTrue:[
^ days + 1
]
].
^ days
! !
!Date class methodsFor:'instance creation'!
today
"return a date, representing today"
^ self basicNew setSecondsLow:(OperatingSystem getTimeLow)
and:(OperatingSystem getTimeHi)
!
fromDays:dayCount
^ self new setDays:dayCount
!
newDay:dayCount year:yearInteger
^ self new setDays:(dayCount + self yearAsDays:yearInteger)
!
newDay:day month:monthName year:yearInteger
^self new setDays:
(day + (self daysUntilMonth: monthName forYear: yearInteger)
+ (self yearAsDays: yearInteger))
"Date newDay:8 month:'may' year:1993"
! !
!Date methodsFor:'comparing'!
< aDate
"return true, if the date represented by the receiver
is before the argument, aDate"
|other|
(aDate isMemberOf:Date) ifTrue:[
OperatingSystem computeDatePartsOf:secondsLow and:secondsHi
for:[:year :month :day |
other := aDate year.
(year < other) ifTrue:[^ true].
(year > other) ifTrue:[^ false].
other := aDate month.
(month < other) ifTrue:[^ true].
(month > other) ifTrue:[^ false].
^ day < aDate day
].
].
^ super < aDate
!
> aDate
"return true, if the date represented by the receiver
is after the argument, aDate"
|other|
(aDate isMemberOf:Date) ifTrue:[
OperatingSystem computeDatePartsOf:secondsLow and:secondsHi
for:[:year :month :day |
other := aDate year.
(year > other) ifTrue:[^ true].
(year < other) ifTrue:[^ false].
other := aDate month.
(month > other) ifTrue:[^ true].
(month < other) ifTrue:[^ false].
^ day > aDate day
].
].
^ super > aDate
!
= aDate
"return true, if the date represented by the receiver
is the same as the one represented by argument, aDate"
(aDate isMemberOf:Date) ifTrue:[
OperatingSystem computeDatePartsOf:secondsLow and:secondsHi
for:[:year :month :day |
(year ~~ aDate year) ifTrue:[^ false].
(month ~~ aDate month) ifTrue:[^ false].
^ (day == aDate day)
]
].
^ super = aDate
! !
!Date methodsFor:'printing'!
printString
|string|
OperatingSystem computeDatePartsOf:secondsLow and:secondsHi
for:[:year :month :day |
string := day printString
, '-'
, (Date abbreviatedNameOfMonth:month)
, '-'
, year printString
].
^ string
! !