[m-rev.] for review: bug fix for library/time.m

Simon Taylor stayl at cs.mu.OZ.AU
Thu May 31 16:28:43 AEST 2001



Estimated hours taken: 0.5
Branches: main, release

library/time.m:
	Fix a bug: type `tm' didn't contain a member to store the
	day of the month, so functions which used that member, for
	example time__mktime, would not work.

	Remove some code duplication in the handling of daylight
	saving time.

	Add field names to type `tm'.

NEWS:
	Document the changes to time.m.

tests/hard_coded/Mmakefile:
tests/hard_coded/time_test.{m,exp}:
	Some basic tests of the time module.


Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.209
diff -u -u -r1.209 NEWS
--- NEWS	2001/05/24 06:06:46	1.209
+++ NEWS	2001/05/31 06:11:46
@@ -30,6 +30,10 @@
 * The exception module has a new predicate `try_store', which is
   like `try_io', but which works with stores rather than io__states.
 
+* We've fixed a bug in time.m. Type `tm' didn't store the day of the month,
+  which meant that predicates which required that field (e.g. time__asctime,
+  time__mktime) did not work.
+
 Changes to the Mercury implementation:
 * We've fixed a long-standing bug in the handling of module imports.
   Previously, if `module1' imported `module2' which imported `module3' in
Index: library/time.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/time.m,v
retrieving revision 1.20
diff -u -u -r1.20 time.m
--- library/time.m	2001/03/15 07:42:27	1.20
+++ library/time.m	2001/05/31 06:02:14
@@ -39,15 +39,19 @@
 
 	% The `tm' type is a concrete type that represents calendar
 	% times, broken down into their constituent components.
-:- type tm --->
-        tm(int,          % Seconds (0-60)
-           int,          % Minutes (0-59)
-           int,          % Hours (after midnight, 0-23)
-           int,          % WeekDay (number since Sunday, 0-6)
-           int,          % YearDay (number since Jan 1st, 0-365)
-           int,          % Month (number since January, 0-11)
-           int,          % Year (number since 1900)
-           maybe(dst)).  % IsDST (is DST in effect?)
+:- type tm
+	---> tm(
+		tm_sec :: int,		% Seconds (0-61)
+					% (60 and 61 are for leap seconds)
+		tm_min :: int,		% Minutes (0-59)
+		tm_hour :: int,		% Hours (after midnight, 0-23)
+		tm_wday :: int,		% WeekDay (number since Sunday, 0-6)
+		tm_mday :: int,		% MonthDay (1-31)
+		tm_yday :: int,		% YearDay (number since Jan 1st, 0-365)
+		tm_mon :: int,		% Month (number since January, 0-11)
+		tm_year :: int,		% Year (number since 1900)
+		tm_dst :: maybe(dst)	% IsDST (is DST in effect?)
+	).
 
 :- type dst
 	--->	standard_time	% no, DST is not in effect
@@ -119,7 +123,7 @@
 :- func time__gmtime(time_t) = tm.
 
 	% time__mktime(TM) = Time:
-	%	Converts the broken-down time value to calendar time.
+	%	Converts the broken-down local time value to calendar time.
 	%	It also normalises the value by filling in day of
 	%	week and day of year based on the other components.
 	%
@@ -318,22 +322,16 @@
 %:- func time__localtime(time_t) = tm.
 
 time__localtime(Time) = TM :-
-	time__c_localtime(Time, Sec, Min, Hrs, WD, YD, Mnt, Yr, N),
-	( N = 0 ->
-		DST = yes(standard_time)
-	; N > 0 ->
-		DST = yes(daylight_time)
-	; % N < 0
-		DST = no
-	),
-	TM = tm(Sec, Min, Hrs, WD, YD, Mnt, Yr, DST).
+	time__c_localtime(Time, Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, N),
+	TM = tm(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, int_to_maybe_dst(N)).
 
-:- pred time__c_localtime(int, int, int, int, int, int, int, int, int).
-:- mode time__c_localtime(in, out, out, out, out, out, out, out, out) is det.
+:- pred time__c_localtime(int, int, int, int, int, int, int, int, int, int).
+:- mode time__c_localtime(in, out, out, out, out, out, out,
+		out, out, out) is det.
 
 :- pragma foreign_proc("C",
 	time__c_localtime(Time::in, Sec::out, Min::out, Hrs::out,
-                                   WD::out, YD::out, Mnt::out,
+                                   WD::out, MD::out, YD::out, Mnt::out,
                                    Yr::out, N::out),
 	[will_not_call_mercury],
 "{
@@ -352,13 +350,14 @@
 	Mnt = (MR_Integer) p->tm_mon;
 	Yr = (MR_Integer) p->tm_year;
 	WD = (MR_Integer) p->tm_wday;
+	MD = (MR_Integer) p->tm_mday;
 	YD = (MR_Integer) p->tm_yday;
 	N = (MR_Integer) p->tm_isdst;
 }").
 
 :- pragma foreign_proc("MC++",
 	time__c_localtime(_Time::in, _Sec::out, _Min::out, _Hrs::out,
-                                   _WD::out, _YD::out, _Mnt::out,
+                                   _WD::out, _MD::out, _YD::out, _Mnt::out,
                                    _Yr::out, _N::out),
 	[will_not_call_mercury],
 "{
@@ -369,22 +368,16 @@
 %:- func time__gmtime(time_t) = tm.
 
 time__gmtime(Time) = TM :-
-	time__c_gmtime(Time, Sec, Min, Hrs, WD, YD, Mnt, Yr, N),
-	( N = 0 ->
-		DST = yes(standard_time)
-	; N > 0 ->
-		DST = yes(daylight_time)
-	; % N < 0
-		DST = no
-	),
-	TM = tm(Sec, Min, Hrs, WD, YD, Mnt, Yr, DST).
+	time__c_gmtime(Time, Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, N),
+	TM = tm(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, int_to_maybe_dst(N)).
 
-:- pred time__c_gmtime(int, int, int, int, int, int, int, int, int).
-:- mode time__c_gmtime(in, out, out, out, out, out, out, out, out) is det.
+:- pred time__c_gmtime(int, int, int, int, int, int, int, int, int, int).
+:- mode time__c_gmtime(in, out, out, out, out, out,
+			out, out, out, out) is det.
 
 :- pragma foreign_proc("C",
 	time__c_gmtime(Time::in, Sec::out, Min::out, Hrs::out,
-                                   WD::out, YD::out, Mnt::out,
+                                   WD::out, MD::out, YD::out, Mnt::out,
                                    Yr::out, N::out),
 	[will_not_call_mercury],
 "{
@@ -403,40 +396,45 @@
 	Mnt = (MR_Integer) p->tm_mon;
 	Yr = (MR_Integer) p->tm_year;
 	WD = (MR_Integer) p->tm_wday;
+	MD = (MR_Integer) p->tm_mday;
 	YD = (MR_Integer) p->tm_yday;
 	N = (MR_Integer) p->tm_isdst;
 }").
 
 :- pragma foreign_proc("MC++",
 	time__c_gmtime(_Time::in, _Sec::out, _Min::out, _Hrs::out,
-                                   _WD::out, _YD::out, _Mnt::out,
+                                   _WD::out, _YD::out, _MD::out, _Mnt::out,
                                    _Yr::out, _N::out),
 	[will_not_call_mercury],
 "{
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 }").
 
+:- func int_to_maybe_dst(int) = maybe(dst).
 
+int_to_maybe_dst(N) = DST :-
+	( N = 0 ->
+		DST = yes(standard_time)
+	; N > 0 ->
+		DST = yes(daylight_time)
+	; % N < 0
+		DST = no
+	).
+
 %-----------------------------------------------------------------------------%
 
 %:- func time__mktime(tm) = time_t.
 
 time__mktime(TM) = Time :-
-	TM = tm(Sec, Min, Hrs, WD, YD, Mnt, Yr, M),
-	( M = yes(DST), DST = daylight_time,
-		N = 1
-	; M = yes(DST), DST = standard_time,
-		N = 0
-	; M = no,
-		N = -1
-	),
-	time__c_mktime(Sec, Min, Hrs, WD, YD, Mnt, Yr, N, Time).
+	TM = tm(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, DST),
+	time__c_mktime(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr,
+		maybe_dst_to_int(DST), Time).
 
-:- pred time__c_mktime(int, int, int, int, int, int, int, int, int).
-:- mode time__c_mktime(in, in, in, in, in, in, in, in, out) is det.
+:- pred time__c_mktime(int, int, int, int, int, int, int, int, int, int).
+:- mode time__c_mktime(in, in, in, in, in, in, in, in, in, out) is det.
 
 :- pragma foreign_proc("C",
-	time__c_mktime(Sec::in, Min::in, Hrs::in, WD::in,
+	time__c_mktime(Sec::in, Min::in, Hrs::in, WD::in, MD::in,
                                 YD::in, Mnt::in, Yr::in,
                                 N::in, Time::out),
 	[will_not_call_mercury],
@@ -449,6 +447,7 @@
 	t.tm_mon = Mnt;
 	t.tm_year = Yr;
 	t.tm_wday = WD;
+	t.tm_mday = MD;
 	t.tm_yday = YD;
 	t.tm_isdst = N;
 
@@ -457,34 +456,38 @@
 
 :- pragma foreign_proc("MC++",
 	time__c_mktime(_Sec::in, _Min::in, _Hrs::in, _WD::in,
-                                _YD::in, _Mnt::in, _Yr::in,
+                                _YD::in, _MD::in, _Mnt::in, _Yr::in,
                                 _N::in, _Time::out),
 	[will_not_call_mercury],
 "{
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 }").
 
+:- func maybe_dst_to_int(maybe(dst)) = int.
 
-%-----------------------------------------------------------------------------%
-
-%:- func time__asctime(tm) = string.
-
-time__asctime(TM) = Str :-
-	TM = tm(Sec, Min, Hrs, WD, YD, Mnt, Yr, M),
+maybe_dst_to_int(M) = N :-
 	( M = yes(DST), DST = daylight_time,
 		N = 1
 	; M = yes(DST), DST = standard_time,
 		N = 0
 	; M = no,
 		N = -1
-	),
-	time__c_asctime(Sec, Min, Hrs, WD, YD, Mnt, Yr, N, Str).
+	).
+
+%-----------------------------------------------------------------------------%
+
+%:- func time__asctime(tm) = string.
+
+time__asctime(TM) = Str :-
+	TM = tm(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr, DST),
+	time__c_asctime(Sec, Min, Hrs, WD, MD, YD, Mnt, Yr,
+		maybe_dst_to_int(DST), Str).
 
-:- pred time__c_asctime(int, int, int, int, int, int, int, int, string).
-:- mode time__c_asctime(in, in, in, in, in, in, in, in, out) is det.
+:- pred time__c_asctime(int, int, int, int, int, int, int, int, int, string).
+:- mode time__c_asctime(in, in, in, in, in, in, in, in, in, out) is det.
 
 :- pragma foreign_proc("C",
-	time__c_asctime(Sec::in, Min::in, Hrs::in, WD::in,
+	time__c_asctime(Sec::in, Min::in, Hrs::in, WD::in, MD::in,
                                  YD::in, Mnt::in, Yr::in, N::in, Str::out),
 	[will_not_call_mercury],
 "{
@@ -497,6 +500,7 @@
 	t.tm_mon = Mnt;
 	t.tm_year = Yr;
 	t.tm_wday = WD;
+	t.tm_mday = MD;
 	t.tm_yday = YD;
 	t.tm_isdst = N;
 
@@ -506,7 +510,7 @@
 }").
 
 :- pragma foreign_proc("MC++",
-	time__c_asctime(_Sec::in, _Min::in, _Hrs::in, _WD::in,
+	time__c_asctime(_Sec::in, _Min::in, _Hrs::in, _WD::in, _MD::in,
                                  _YD::in, _Mnt::in, _Yr::in, _N::in,
 				 _Str::out),
 	[will_not_call_mercury],
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.118
diff -u -u -r1.118 Mmakefile
--- tests/hard_coded/Mmakefile	2001/05/27 09:59:54	1.118
+++ tests/hard_coded/Mmakefile	2001/05/30 18:02:01
@@ -113,6 +113,7 @@
 	test_bitset \
 	test_imported_no_tag \
 	tim_qual1 \
+	time_test \
 	tuple_test \
 	tuple_test \
 	type_ctor_desc \
Index: tests/hard_coded/time_test.exp
===================================================================
RCS file: time_test.exp
diff -N time_test.exp
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ time_test.exp	Thu May 31 16:15:29 2001
@@ -0,0 +1,3 @@
+mktime succeeded
+Sun Jan  7 03:02:01 2001
+
Index: tests/hard_coded/time_test.m
===================================================================
RCS file: time_test.m
diff -N time_test.m
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ time_test.m	Thu May 31 16:15:11 2001
@@ -0,0 +1,25 @@
+:- module time_test.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, time.
+
+main -->
+	time(Time),
+	( { mktime(localtime(Time)) = Time } ->
+		io__write_string("mktime succeeded\n")
+	;
+		io__write_string("mktime failed\n")
+	),
+	
+	% Sunday 2001-01-07 03:02:01
+	{ TM = tm(1, 2, 3, 0, 7, 6, 0, 101, no) },
+	io__write_string(asctime(TM)),
+	io__nl.
+
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list