
!"Pocket Smalltalk fileout - 11:23:46 AM, Tuesday, February 09, 1999"!


!Object constantsFor: 'Date Constants'!

dfDBYLongWithDot 9! 
dfDMYLong 8! 
dfDMYLongNoDay 10! 
dfDMYLongWithComma 11! 
dfDMYWithDashes 3! 
dfDMYWithDots 2! 
dfDMYWithSlashes 1! 
dfMDYLongWithComma 7! 
dfMDYWithSlashes 0! 
dfMYMed 14! 
dfYMDLongWithDot 12! 
dfYMDLongWithSpace 13! 
dfYMDWithDashes 6! 
dfYMDWithDots 5! 
dfYMDWithSlashes 4! 
selectDayByDay 0! 
selectDayByMonth 2! 
selectDayByWeek 1! !

Object subclass: #Date
	instanceVariableNames: 'year month day'
	classVariableNames: ''!

Object subclass: #DateAndTime
	instanceVariableNames: 'second minute hour day month year weekDay'
	classVariableNames: ''!

Object subclass: #Time
	instanceVariableNames: 'hour minute'
	classVariableNames: ''!

!Date methodsFor: 'date functions'!

addDays: days
	PadBuffer wordAt: 0 put: self asDateType.
	SYSTRAP DateAdjust: PadBuffer adjustment: days.
	^self new fromDateType: (PadBuffer wordAt: 0).! !


!Date methodsFor: 'printing'!

printString: dateFormat
	"dateFormat is one of the ##df* constants."
	| pad |
	pad := PadBuffer.
	SYSTRAP
		DateToAscii: (month bitShift: 8)
		days: (day bitShift: 8)
		years: year
		format: (dateFormat bitShift: 8)
		string: pad.
	^pad extractCString.
!

printOn: stream
	stream nextPutAll: (self printString: ##dfMDYLongWithComma).! !


!Date methodsFor: 'accessing'!

year
	^year.!

month
	^month.!

day
	^day.! !


!Date methodsFor: 'initialization'!

year: years month: months day: days
	year := years.
	month := months.
	day := days.! !


!Date methodsFor: 'private'!

asDateType
	^(year bitShift: 9) bitOr:
		((month bitShift: 5) bitOr: day).!

fromDateType: dateType
	year := (dateType bitShift: -9) bitAnd: 127.
	month := (dateType bitShift: -5) bitAnd: 15.
	day := dateType bitAnd: 31.! !


!Date class methodsFor: 'instance creation'!

now
	^DateAndTime now date.!

year: years month: months day: days
	^self new year: years month: months day: days.!

selectDate
	^self
		selectDate: self now
		by: ##selectDayByMonth
		caption: 'Select Date'.!

selectDate: date by: selectionType caption: caption
	"Pop up a date selector.  If the user selects a new date, write the new values back into the dateAndTime object and answer true.  If no date is selected, do nothing and answer false."
	"selectionType is a ##selectDayBy* constant."
	| pad accepted captionPtr |
	pad := PadBuffer.
	pad
		wordAt: 0 put: date month;
		wordAt: 2 put: date day;
		wordAt: 4 put: date year.
	captionPtr := caption copyToHeap.
	accepted := SYSTRAP
		SelectDay: selectionType
		month: pad
		day: (pad offsetBy: 2)
		year: (pad offsetBy: 4)
		title: caption.
	captionPtr free.
	^accepted asBoolean
		ifTrue: [
			self 
				year: (pad wordAt: 4)
				month: (pad wordAt: 0)
				day: (pad wordAt: 2)]
		ifFalse: [nil].! !


!DateAndTime comment!
DateAndTime represents a point in time with 1-second resolution.  Get the current DateAndTime with the class-side message #now.! !


!DateAndTime methodsFor: 'printing'!

printOn: stream
	stream
		print: self date;
		nextPut: $,;
		space;
		print: self time.
! !


!DateAndTime methodsFor: 'accessing'!

second
	^second.!

minute
	^minute.!

hour
	^hour.!

day
	^day.!

month
	^month.!

year
	^year.!

weekDay
	^weekDay.!

time
	^Time hour: hour minute: minute.!

date
	^Date year: year month: month day: day.! !


!DateAndTime methodsFor: 'private'!

destructureFromPad: pad
	second := pad wordAt: 0.
	minute := pad wordAt: 2.
	hour := pad wordAt: 4.
	day := pad wordAt: 6.
	month := pad wordAt: 8.
	year := pad wordAt: 10.
	weekDay := pad wordAt: 12.!

copyIntoPad: pad
	pad 
		wordAt: 0 put: second;
		wordAt: 2 put: minute;
		wordAt: 4 put: hour;
		wordAt: 6 put: day;
		wordAt: 8 put: month;
		wordAt: 10 put: year;
		wordAt: 12 put: weekDay.! !


!DateAndTime methodsFor: 'time functions'!

addSeconds: seconds
	^self copy adjustBySeconds: seconds.!

addDays: days
	^self addSeconds: (self class forDays: days) asSeconds.!

asSeconds
	| pad |
	pad := PadBuffer.
	self copyIntoPad: pad.
	^SYSTRAP TimDateTimeToSeconds: pad.!

adjustBySeconds: seconds
	"Add 'seconds' (positive or negative) to the receiver, destructively."
	| pad |
	pad := PadBuffer.
	self copyIntoPad: pad.
	SYSTRAP DateAdjust: pad by: seconds.
	self destructureFromPad: pad.! !


!DateAndTime class methodsFor: 'date functions'!

daysInMonth: monthNumber year: year
	"monthNumber is 1..12.  Answer the number of days in the given month."
	^SYSTRAP DaysInMonth: monthNumber year: year.!

dayOfWeek: dayNumber month: monthNumber year: yearNumber
	"Answer the day of the week (0=Sunday, 1=Monday...)"
	^SYSTRAP
		DayOfWeek: monthNumber
		day: dayNumber
		year: yearNumber.!

secondsSinceEpoch
	^SYSTRAP TimGetSeconds.! !


!DateAndTime class methodsFor: 'instance creation'!

forDays: days
	"days since 1/1/1904"
	| pad |
	pad := PadBuffer.
	SYSTRAP DateDaysToDate: days datePtr: pad.
	^self new destructureFromPad: pad.!

now
	^self forSeconds: self secondsSinceEpoch.!

forSeconds: seconds
	| pad |
	pad := PadBuffer.
	SYSTRAP TimSecondsToDateTime: seconds datePtr: pad.
	^self new destructureFromPad: pad.! !


!Time methodsFor: 'initialization'!

hour: hours minute: minutes
	hour := hours.
	minute := minutes.! !


!Time methodsFor: 'printing'!

printString: useAMPM
	"useAMPM is true to use AM/PM designations, false to not use designations."
	| pad |
	pad := PadBuffer.
	SYSTRAP
		TimeToAscii: (hour bitShift: 8)
		minutes: (minute bitShift: 8)
		format: (useAMPM asInteger bitShift: 8)
		string: pad.
	^pad extractCString.!

printOn: stream
	stream nextPutAll: (self printString: true).! !


!Time methodsFor: 'accessing'!

minute
	^minute.!

hour
	^hour.! !


!Time methodsFor: 'private'!

asTimeType
	"convert to the stupid PalmOS pseudostruct"
	^(hour bitShift: 8) bitOr: minute.!

fromTimeType: timeType
	minute := timeType bitAnd: 255.
	hour := (timeType bitShift: -8) bitAnd: 255.! !


!Time class methodsFor: 'instance creation'!

now
	^DateAndTime now time.!

hour: hours minute: minutes
	^self new hour: hours minute: minutes.!

selectTimeRangeFrom: initialStart 
to: initialEnd
untimed: isUntimed
startingHour: startingHour
caption: caption
	"Answers nil if no time was selected.  If a time was selected, answers a two element Array with the start and end times.  If the user sets the time to no time then #untimed is answered."
	| pad accepted captionPtr |
	pad := PadBuffer.
	pad wordAt: 0 put: initialStart asTimeType.
	pad wordAt: 2 put: initialEnd asTimeType.
	captionPtr := caption copyToHeap.
	accepted := SYSTRAP
		SelectTime: pad
		endTimeP: (pad offsetBy: 2)
		untimed: isUntimed asInteger
		title: captionPtr
		startOfDay: startingHour.
	captionPtr free.
	(pad wordAt: 0) = 65535 ifTrue: [^#untimed].
	^accepted asBoolean
		ifTrue: [
			Array
				with: (self new fromTimeType: (pad wordAt: 0))
				with: (self new fromTimeType: (pad wordAt: 2))]
		ifFalse: [nil].! !


