diff -r aa2498ef6470 -r a27a279701f8 Date.st --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Date.st Fri Jul 16 11:39:45 1993 +0200 @@ -0,0 +1,476 @@ +" + COPYRIGHT (c) 1989-92 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. + ---------------------------------------------------------------- +" + +Magnitude subclass:#Date + instanceVariableNames:'unixTimeLow unixTimeHi' + classVariableNames:'dayNames monthNames dayAbbrevs monthAbbrevs + environmentChange' + poolDictionaries:'' + category:'Magnitude-General' +! + +Date comment:' + +COPYRIGHT (c) 1989-92 by Claus Gittinger + All Rights Reserved + +date represents a particular second in a day; since we depend on +unix, the second is counted from 1. Jan 1970 NOT as in Smalltalk-80 +from 1. Jan 1901 ! + +%W% %E% + +written Spring 89 by claus +'! + +!Date class methodsFor:'private'! + +initNames + "read the language specific names" + + dayNames := Resource array:#('DAY_MONDAY' + 'DAY_TUESDAY' + 'DAY_WEDNESDAY' + 'DAY_THURSDAY' + 'DAY_FRIDAY' + 'DAY_SATURDAY' + 'DAY_SUNDAY') + defaults:#('monday' + 'tuesday' + 'wednesday' + 'thursday' + 'friday' + 'saturday' + 'sunday') + fromFile:'Smalltalk.rs'. + + dayAbbrevs := Resource array:#('DAY_MON' + 'DAY_TUE' + 'DAY_WED' + 'DAY_THU' + 'DAY_FRI' + 'DAY_SAT' + 'DAY_SUN') + defaults:#('mon' + 'tue' + 'wed' + 'thu' + 'fri' + 'sat' + 'sun') + fromFile:'Smalltalk.rs'. + + monthNames := Resource array:#('MON_JANUARY' + 'MON_FEBRUARY' + 'MON_MARCH' + 'MON_APRIL' + 'MON_MAY' + 'MON_JUNE' + 'MON_JULY' + 'MON_AUGUST' + 'MON_SEPTEMBER' + 'MON_OCTOBER' + 'MON_NOVEMBER' + 'MON_DECEMBER') + defaults:#('january' + 'february' + 'march' + 'april' + 'may' + 'june' + 'july' + 'august' + 'september' + 'october' + 'november' + 'december') + fromFile:'Smalltalk.rs'. + + monthAbbrevs := Resource array:#('MON_JAN' + 'MON_FEB' + 'MON_MAR' + 'MON_APR' + 'MON_MAY_ABBREV' + 'MON_JUN' + 'MON_JUL' + 'MON_AUG' + 'MON_SEP' + 'MON_OCT' + 'MON_NOV' + 'MON_DEC') + defaults:#('jan' + 'feb' + 'mar' + 'apr' + 'may' + 'jun' + 'jul' + 'aug' + 'sep' + 'oct' + 'nov' + 'dec') + fromFile:'Smalltalk.rs'. + + environmentChange := false +! ! + +!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). + 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'! + +dateAndTimeNow + "return an array with the current date and time" + + ^ Array with:(Date today) with:(Time now) +! + +today + "return a date, representing today" + + ^ self basicNew setTimeLow:(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 after the argument, aDate" + + |other| + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + 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 + ] +! + += aDate + "return true, if the date represented by the receiver + is the same as the one represented by argument, aDate" + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + for:[:year :month :day | + (year ~~ aDate year) ifTrue:[^ false]. + (month ~~ aDate month) ifTrue:[^ false]. + ^ (day == aDate day) + ] +! ! + +!Date methodsFor:'accessing'! + +day + "return the day-in-month of the receiver (1..31)" + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + for:[:year :month :day | + ^ day + ] +! + +month + "return the month of the receiver (1..12)" + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + for:[:year :month :day | + ^ month + ] +! + +year + "return the year of the receiver i.e. 1992" + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + for:[:year :month :day | + ^ year + ] +! ! + +!Date methodsFor:'printing'! + +printString + |string| + + OperatingSystem computeDatePartsOf:unixTimeLow and:unixTimeHi + for:[:year :month :day | + string := day printString + , '-' + , (Date abbreviatedNameOfMonth:month) + , '-' + , year printString + ]. + ^ string +! ! + +!Date methodsFor:'storing'! + +storeString + |string| + string := '(' , self class name , ' new settimeLow:'. + string := string , unixTimeLow storeString. + string := string , ' and:' , unixTimeHi storeString. + string := string , ')'. + ^ string +! ! + +!Date methodsFor:'private'! + +setTimeLow:timeLow and:timeHi + unixTimeLow := timeLow. + unixTimeHi := timeHi +! ! + +!Date methodsFor:'converting'! + +asSeconds + ^ (unixTimeHi * 16r10000) + unixTimeLow +! !