requires: {#Magnitude}. provides: {#Time. #Date. #Duration. #Month}. "Date and Time protocols, included from ANSI Smalltalk packages for Squeak." lobby addSlot: #Time valued: Namespace clone. Time addSlot: #Time valued: Magnitude derive. Time Time addSlot: #seconds. "Time represents an amount of time within a 24-hour period, stored as seconds." t@(Time Time traits) newForSeconds: n [| newT | newT: t clone. newT seconds: n. newT ]. t@(Time Time traits) newForHours: h minutes: m seconds: s [| newT | newT: t clone. newT seconds: h * 3600 + (m * 60) + s. newT ]. t@(Time Time traits) hours "Answer the number of hours the receiver represents." [ t seconds // 3600 \\ 24 ]. t@(Time Time traits) minutes "Answer the number of minutes the receiver represents." [ t seconds \\ 3600 // 60 ]. t@(Time Time traits) seconds "Answer the number of seconds the receiver represents." [ t seconds \\ 60 ]. t1@(Time Time traits) + t2@(Time Time traits) [ t1 newForSeconds: t1 seconds + t2 seconds ]. t1@(Time Time traits) - t2@(Time Time traits) [ t1 newForSeconds: t1 seconds - t2 seconds ]. t1@(Time Time traits) < t2@(Time Time traits) [ t1 seconds < t2 seconds ]. t1@(Time Time traits) = t2@(Time Time traits) [ t1 seconds = t2 seconds ]. t@(Time Time traits) hash [ t seconds hash ]. Time addSlot: #Date valued: Magnitude derive. Time Date addSlot: #julianDayNumber. Time addSlot: #DaysInMonth. Time addSlot: #FirstDayOfMonth. Time addSlot: #MonthNames. Time addSlot: #SecondsInDay. Time addSlot: #WeekDayNames. Time addSlot: #Month valued: Cloneable derive. Time Month addSlot: #name valued: ''. Time Month addSlot: #firstDayWithinYear valued: 0. Time Month addSlot: #length valued: 0. m@(Time Month traits) newNamed: name startingAt: start length: length [| newM | newM: m clone. newM name: name. newM firstDayWithinYear: start. newM length: length. newM ]. m@(Time Month traits) newNamed: name from: start to: end [ m newNamed: name startingAt: start length: end - start + 1 ]. Time addSlot: #months valued: Namespace clone. Time months addSlot: #January valued: (Month newNamed: 'January' startingAt: 1 length: 31). Time months addSlot: #January valued: (Month newNamed: 'February' startingAt: 32 length: 28). Time months addSlot: #March valued: (Month newNamed: 'March' startingAt: 60 length: 31). Time months addSlot: #April valued: (Month newNamed: 'April' startingAt: 91 length: 30). Time months addSlot: #May valued: (Month newNamed: 'May' startingAt: 121 length: 31). Time months addSlot: #June valued: (Month newNamed: 'June' startingAt: 152 length: 30). Time months addSlot: #July valued: (Month newNamed: 'July' startingAt: 182 length: 31). Time months addSlot: #August valued: (Month newNamed: 'August' startingAt: 213 length: 31). Time months addSlot: #September valued: (Month newNamed: 'September' startingAt: 244 length: 30). Time months addSlot: #October valued: (Month newNamed: 'October' startingAt: 274 length: 31). Time months addSlot: #November valued: (Month newNamed: 'November' startingAt: 305 length: 30). Time months addSlot: #December valued: (Month newNamed: 'December' startingAt: 335 length: 31). Time addSlot: #JulianMonths valued: (Set newSize: 12). Time months slotValuesDo: [| :each | Time JulianMonths add: each]. Time addSlot: #Duration valued: Magnitude derive. Duration addSlot: #seconds valued: 0. d@(Time Duration traits) newForSeconds: n [| newD | newD: d clone. newD seconds: n. newD ]. d@(Time Duration traits) days "The number of whole days represented, possibly negative." [ d seconds abs // Time SecondsInDay * d seconds sign ]. d@(Time Duration traits) hours "The number of whole hours represented, possibly negative, after whole days are discounted." [ d seconds abs \\ Time SecondsInDay // Time SecondsInHour * d seconds sign ]. d@(Time Duration traits) minutes "The number of whole minutes, possibly negative, after whole days and hours are discounted." [ d seconds abs \\ Time SecondsInDay \\ Time SecondsInHour // Time SecondsInMinute * d seconds sign ]. d@(Time Duration traits) seconds "The number of seconds, possibly negative, after whole days, hours, minutes are discounted." [ d seconds abs \\ Time SecondsInDay \\ Time SecondsInHour \\ Time SecondsInMinute * d seconds sign ]. d@(Time Duration traits) * n@(Number traits) [ d newForSeconds: d seconds * n ]. d@(Time Duration traits) / n@(Number traits) [ d newForSeconds: d seconds / n ]. d1@(Time Duration traits) / d2@(Time Duration traits) [ d1 seconds / d2 seconds ]. d1@(Time Duration traits) + d2@(Time Duration traits) [ d newForSeconds: d1 seconds + d2 seconds ]. d1@(Time Duration traits) - d2@(Time Duration traits) [ d newForSeconds: d1 seconds - d2 seconds ]. d@(Time Duration traits) abs [ d newForSeconds: d seconds abs ]. d@(Time Duration traits) negated [ d newForSeconds: d seconds negated ]. d@(Time Duration traits) isZero [ d seconds isZero ]. d@(Time Duration traits) sign [ d seconds sign ]. d@(Time Duration traits) isPositive [ d seconds isPositive ]. d@(Time Duration traits) isNegative [ d seconds isNegative ]. d1@(Time Duration traits) < d2@(Time Duration traits) [ d1 seconds < d2 seconds ]. d1@(Time Duration traits) > d2@(Time Duration traits) [ d1 seconds > d2 seconds ]. d1@(Time Duration traits) = d2@(Time Duration traits) [ d1 seconds = d2 seconds ]. d@(Time Duration traits) hash [ d seconds hash ]. d@(Time Duration traits) printAbsOn: stream "Prints out the format [-]D:HH:MM:SS[.S] ." [| tempSecs | stream ; (d days abs printPaddedWith: $0 to: 1). stream nextPut: $:. stream ; (d hours abs printPaddedWith: $0 to: 2). stream nextPut: $:. stream ; (d minutes abs printPaddedWith: $0 to: 2). tempSecs: d seconds abs. tempSecs fractionPart = 0 ifTrue: [tempSecs: (tempSecs as: Integer)]. stream ; (tempSecs printPaddedWith: $0 to: 2). d ]. d@(Time Duration traits) printOn: stream [ d seconds isNegative ifTrue: [stream nextPut: $-]. d printAbsOn: stream ]. Time addSlot: #SecondsInMinute valued: 60. Time addSlot: #SecondsInHour valued: Time SecondsInMinute * 60. Time addSlot: #SecondsInDay valued: Time SecondsInHour * 24. Time addSlot: #Instant valued: Magnitude derive. Time Instant addSlot: #localDate. Time Instant addSlot: #localOffsetToUTC. Time Instant addSlot: #localTime. Time Instant addSlot: #localTimeZoneName. Time Instant addSlot: #localTimeZoneAbbrev. "Instant instances represent individual points in Coordinated Universal Time (UTC) formerly called GMT at Greenwich, UK as represented in an implementation defined local time, including consideration of time zones." i@(Time Instant traits) dayOfMonth "Answer an Integer between 1 and 31, inclusive, representing the day of the month in the local time of the receiver, which includes the receiver." [ i localDate dayOfMonth ]. i@(Time Instant traits) dayOfWeek "Answer an Integer between 1 and 7, inclusive, representing the day of the week in the local time of the receiver, which includes the receiver. Sunday is 1, Monday 2, and so on." [| dayIndex | dayIndex: i localDate weekdayIndex + 1. dayIndex > 7 ifTrue: [dayIndex: 1]. dayIndex ]. i@(Time Instant traits) dayOfWeekAbbreviation [ i dayOfWeekName copyFrom: 0 to: 2 ]. i@(Time Instant traits) dayOfWeekName "Answer the name of the day of the week in the local time." [ i localDate weekday as: String ]. i@(Time Instant traits) dayOfYear "Answer an Integer between 1 and 366, inclusive, representing the day of the year in the local time of the receiver, which includes the receiver." [ i localDate day ]. i@(Time Instant traits) hour "Answer an Integer between 0 and 23, inclusive, representing the hour of the day in the local time of the receiver. This may be in either the 12 or 24 hour clock." [ i localTime hours ]. i@(Time Instant traits) hour24 [ i hour ]. i@(Time Instant traits) hour12 "Answer an Integer between 1 and 12, inclusive, representing the hour of the day in the 12-hour clock of the local time of the receiver." [| tempHour | tempHour: (self hour + 1) abs. tempHour > 12 ifTrue: [tempHour: tempHour - 12]. tempHour ]. i@(Time Instant traits) minute "Answer an Integer between 0 and 59, inclusive, representing the minute of the hour in the local time of the receiver." [ i localTime minutes ]. i@(Time Instant traits) second "Answer an Integer between 0 and 59, inclusive, representing the second of the minute in the local time of the receiver, including the fractional part." [ i localTime seconds abs ]. i@(Time Instant traits) year "Answer an Integer representing the year of the local time which includes the receiver." [ i localDate year ]. i@(Time Instant traits) month "Answer an Integer between 1 and 12, inclusive, representing the month of the year in the local time of the receiver." [ i localDate monthIndex ]. i@(Time Instant traits) monthName "Answer the name of the month of the year in the local time of the receiver, which includes the receiver." [ i localDate monthName as: String ]. i@(Time Instant traits) monthAbbreviation "Answer a which is the abbreviated name of the month of the year in the local time of the receiver, which includes the receiver." [ i monthName copyFrom: 0 to: 2 ]. i@(Time Instant traits) offset [ i localOffsetToUTC ]. i@(Time Instant traits) offset: d@(Time Duration traits) "Answer an Instant equivalent to the receiver, but with its local time offset from UTC by the Duration." [| newI | d abs < Time Day ifFalse: [i error: 'Invalid UTC-offset.']. newI: i clone. newI localOffsetToUTC: d. newI ]. i@(Time Instant traits) rationalise "Adjust the receiver so localTime is less than a day and positive." [| timeDays | i localTime isNegative ifTrue: [ timeDays: i localTime days abs + 1. i localDate: (i localDate subtractDays: timeDays). i localTime: (Duration days: timeDays) + i localTime]. "Insure time is less than a day." timeDays: i localTime days. timeDays > 0 ifTrue: [i localDate: (i localDate addDays: timeDays). i localTime: i localTime - (Duration days: timeDays)]. i ]. i@(Time Instant traits) + d@(Time Duration traits) [| newI | newI: i clone. newI localTime: i localTime + d. newI rationalise. newI ]. i@(Time Instant traits) - d@(Time Duration traits) [ i + d negated ]. i1@(Time Instant traits) - i2@(Time Instant traits) [ Duration newSeconds: i2 localDate - i1 localDate + (i2 localTime - i1 localTime) ]. Time addSlot: #DaylightEndDate. Time addSlot: #DaylightOffset. Time addSlot: #DaylightStartDate. Time addSlot: #DaylightTimeZoneAbbrev. Time addSlot: #DaylightTimeZoneName. Time addSlot: #DaysInMonth. Time addSlot: #DaysToMonth. Time addSlot: #DefaultIsStandard. Time addSlot: #Offset. Time addSlot: #StandardOffset. Time addSlot: #StandardTimeZoneAbbrev. Time addSlot: #StandardTimeZoneName. Time addSlot: #TimeZoneAbbrev. Time addSlot: #TimeZoneName. Time addSlot: #Duration valued: Magnitude derive.