Re: time / update problem

Frederic Merizen <[email protected]> Wed, 20 Jul 2005 11:00:59 +0200
Newsgroups gmane.comp.lang.eiffel.smalleiffel
Message-ID <[email protected]>
Cheng-Chang Wu wrote:
> > --- Philippe Ribet <[email protected]> wrote:
> > > >How can we set the initial value of a user
> >
> > defined
> >
> > > >immutable expanded type to a value different from
> > >
> > > the
> > >
> > > >default value?
> > >
> > > default_create should do the work
>
> But with default_create we always get the same
> initial value, There is no way to change that value
> because the class is immutable.

TIME can have more than one creation procedure (see attached file). Besides, 
integers are immutable expandeds and they work very well.
time.e (text/x-c++src, 7.9 KB)
-- See the Copyright notice at the end of this file.
--
expanded class TIME
	--
	-- Time and date facilities: year, month, day, hour and seconds.
	--

inherit
	HASHABLE
	COMPARABLE
		redefine is_equal
		end

creation {ANY}
	default_create, update, set, add_second

creation {MICROSECOND_TIME, FILE_TOOLS}
	set_time_memory

feature {ANY}
	is_local_time: BOOLEAN is
			-- Is the local time in use? This information applies to all objects
			-- of class TIME and MICROSECOND_TIME.
		do
			Result := time_mode = 0
		ensure
			Result implies not is_universal_time
		end

	is_universal_time: BOOLEAN is
			-- Is Universal Time in use?  This information applies to all objects
			-- of class TIME and MICROSECOND_TIME.
		do
			Result := time_mode /= 0
		ensure
			Result implies not is_local_time
		end

	year: INTEGER is
			-- Number of the year.
		do
			Result := time_getyear(time_memory, time_mode)
		end

	month: INTEGER is
			-- Number of the month (1 for January, 2 for February, ...
			-- 12 for December).
		do
			Result := time_getmonth(time_memory, time_mode)
		ensure
			Result.in_range(1, 12)
		end

	day: INTEGER is
			-- Day of the `month' in range 1 .. 31.
		do
			Result := time_getday(time_memory, time_mode)
		ensure
			Result.in_range(1, 31)
		end

	hour: INTEGER is
			-- Hour in range 0..23.
		do
			Result := time_gethour(time_memory, time_mode)
		ensure
			Result.in_range(0, 23)
		end

	minute: INTEGER is
			-- Minute in range 0 .. 59.
		do
			Result := time_getminute(time_memory, time_mode)
		ensure
			Result.in_range(0, 59)
		end

	second: INTEGER is
			-- Second in range 0 .. 59.
		do
			Result := time_getsecond(time_memory, time_mode)
		ensure
			Result.in_range(0, 59)
		end

	week_day: INTEGER is
			-- Number of the day in the week (Sunday is 0, Monday is 1, etc.).
		do
			Result := time_getwday(time_memory, time_mode)
		ensure
			Result.in_range(0, 6)
		end

	year_day: INTEGER is
			-- Number of the day in the year in range 0 .. 365.
		do
			Result := time_getyday(time_memory, time_mode)
		end

	is_summer_time_used: BOOLEAN is
			-- Is summer time in effect?
		do
			Result := time_is_summer_time_used(time_memory)
		end

	to_microsecond_time: MICROSECOND_TIME is
		do
			Result.set_time(Current)
		ensure
			Result.time = Current
			Result.microsecond = 0
		end

feature {} -- Setting:
	update is
			-- Update `Current' with the current system clock.
		do
			time_memory := basic_time
		end

	set (a_year, a_month, a_day, a_hour, a_min, sec: INTEGER) is
			-- Try to set `Current' using the given information. If this input
			-- is not a valid date, the `Result' is False and `Current' is not updated.
		require
			valid_month: a_month.in_range(1, 12)
			valid_day: a_day.in_range(1, 31)
			valid_hour: a_hour.in_range(0, 23)
			valid_minute: a_min.in_range(0, 59)
			valid_second: sec.in_range(0, 59)
		local
			tm: like time_memory
		do
			tm := time_mktime(a_year, a_month, a_day, a_hour, a_min, sec)
			if tm /= -1 then
				time_memory := tm
			end
		end

	add_second (other: like Current; s: INTEGER) is
			-- Set `Current' to `other' plus `s' seconds.
		require
			s >= 0
		do
			time_add_second($time_memory, s)
		ensure
			Current >= old other
		end

feature {ANY}
	elapsed_seconds (other: like Current): REAL is
			-- Elapsed time in seconds from `Current' to `other'.
		require
			Current <= other
		do
			Result := time_difftime(other.time_memory, time_memory)
		ensure
			Result >= 0
		end

	is_equal (other: like Current): BOOLEAN is
		do
			Result := other.time_memory = time_memory
		end

	infix "<" (other: like Current): BOOLEAN is
		do
			Result := time_difftime(other.time_memory, time_memory) > 0
		end

feature {ANY} -- Setting common time mode (local or universal):
	set_universal_time is
		do
			time_mode_memo.set_item(1)
		ensure
			is_universal_time
		end

	set_local_time is
		do
			time_mode_memo.set_item(0)
		ensure
			is_local_time
		end

feature {ANY} -- Hashing:
	hash_code: INTEGER is
		do
			Result := time_memory.hash_code
		end

feature {}
	set_time_memory (tm: like time_memory) is
		do
			time_memory := tm
		ensure
			time_memory = tm
		end

feature {TIME, TIME_FORMATTER}
	time_memory: INTEGER_64
			-- The current time value of `Current'. As far as we know, this
			-- kind of information should always fit into an INTEGER_64.

feature {}
	time_mode_memo: REFERENCE[INTEGER] is
			-- The global default `time_mode' memory.
		once
			create Result
		end

	time_mode: INTEGER is
		do
			Result := time_mode_memo.item
		ensure
			Result = 0 or Result = 1
		end

	basic_time: INTEGER_64 is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "basic_time"
			}"
		end

	time_difftime (time2, time1: INTEGER_64): REAL is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_difftime"
			}"
		end

	time_getyear (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getyear"
			}"
		end

	time_getmonth (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getmonth"
			}"
		end

	time_getday (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getday"
			}"
		end

	time_gethour (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_gethour"
			}"
		end

	time_getminute (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getminute"
			}"
		end

	time_getsecond (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getsecond"
			}"
		end

	time_is_summer_time_used (tm: INTEGER_64): BOOLEAN is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_is_summer_time_used"
			}"
		end

	time_getyday (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getyday"
			}"
		end

	time_getwday (tm: INTEGER_64; mode: INTEGER): INTEGER is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_getwday"
			}"
		end

	time_mktime (a_year, a_mon, a_day, a_hour, a_min, a_sec: INTEGER): INTEGER_64 is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_mktime"
			}"
		end

	time_add_second (time: POINTER; s: INTEGER) is
		external "plug_in"
		alias "{
			location: "${sys}plugins"
			module_name: "time"
			feature_name: "time_add_second"
			}"
		end

end -- class TIME
--
-- ------------------------------------------------------------------------------------------------------------------------------
-- Copyright notice below. Please read.
--
-- This file is free software, which comes along with SmartEiffel. This software 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.
-- You can modify it as you want, provided this footer is kept unaltered, and a notification of the changes is added.
-- You are allowed to redistribute it and sell it, alone or as a part of another product.
--
-- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P.       - University of Nancy 1 - FRANCE
-- Copyright(C) 2003-2004: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
--
-- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
--
-- http://SmartEiffel.loria.fr - [email protected]
-- ------------------------------------------------------------------------------------------------------------------------------