[m-rev.] for review: Implementation of time library in Java

James Goddard goddardjames at yahoo.com
Mon Dec 15 12:30:04 AEDT 2003


Estimated hours taken: 6
Branches: main

Implemented some library functions for the time library in java.

library/time.m:
	Foreign type "time_t_rep" implemented as "java.util.Date".

	Implemented the following predicates in java:

		time__clock/3
		time__clocks_per_sec/0	<-- also removed intermediate
					    time__c_clocks_per_sec/1
		time__c_times/7
		time__clk_tck/0
		time__c_time/3
		time__time_t_is_invalid/1
		time__c_difftime/3
		time__c_localtime/10
		time__c_gmtime/10
		time__c_mktime/10

	Implemented the following predicates as mercury clauses:
	(So as to suppress errors about not being implemented in Java)

		time__c_clock/3
		time__c_clk_tck/0


Index: time.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/time.m,v
retrieving revision 1.38
diff -u -d -r1.38 time.m
--- time.m	2 Nov 2003 01:04:24 -0000	1.38
+++ time.m	15 Dec 2003 01:15:10 -0000
@@ -216,6 +216,9 @@
 :- pragma foreign_type(il, time_t_rep, "valuetype [mscorlib]System.DateTime")
 	where comparison is compare_time_t_reps.
 
+:- pragma foreign_type("Java", time_t_rep, "java.util.Date")
+	where comparison is compare_time_t_reps.
+
 :- pred compare_time_t_reps(comparison_result::uo,
 		time_t_rep::in, time_t_rep::in) is det.
 compare_time_t_reps(Result, X, Y) :-
@@ -252,28 +255,45 @@
 		.UserProcessorTime.Ticks;
 }").
 */
+time__c_clock(-1, IO, IO). % default will throw an exception.
 
-%-----------------------------------------------------------------------------%
+% The Java implementation is of time__clock/3 directly rather than
+% time__c_clock/3 since Java's equivalent method never returns a value
+% indicating failure.
+:- pragma foreign_proc("Java", time__clock(Ret::out, _IO0::di, _IO::uo),
+        [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+	// System.currentTimeMillis() returns a long (64 bit) integer which
+	// represents the number of milliseconds since
+	// January 1, 1970, 00:00:00 GMT.
+	// This is cast to type int, discarding the high order bits, which is
+	// ok since time__clock/3's base time is defined as being arbitrary.
 
-%:- func time__clocks_per_sec = int.
+	Ret = (int) System.currentTimeMillis();
+	succeeded = true;
+").
 
-time__clocks_per_sec = Val :-
-	time__c_clocks_per_sec(Val).
+%-----------------------------------------------------------------------------%
 
-:- pred time__c_clocks_per_sec(int).
-:- mode time__c_clocks_per_sec(out) is det.
+%:- func time__clocks_per_sec = int.
 
-:- pragma foreign_proc("C", time__c_clocks_per_sec(Ret::out),
+:- pragma foreign_proc("C", time__clocks_per_sec = (Ret::out),
 	[will_not_call_mercury, promise_pure],
 "{
 	Ret = (MR_Integer) CLOCKS_PER_SEC;
 }").
-:- pragma foreign_proc("C#", time__c_clocks_per_sec(Ret::out),
+:- pragma foreign_proc("C#", time__clocks_per_sec = (Ret::out),
 	[will_not_call_mercury, promise_pure],
 "{
 	// TicksPerSecond is guaranteed to be 10,000,000
 	Ret = (int) System.TimeSpan.TicksPerSecond;
 }").
+:- pragma foreign_proc("Java", time__clocks_per_sec = (Ret::out),
+	[will_not_call_mercury, promise_pure],
+"
+	// Java only supports millisecond precision.
+	Ret = 1000;
+").
 
 %-----------------------------------------------------------------------------%
 
@@ -312,6 +332,17 @@
 	MR_update_io(IO0, IO);
 }").
 
+:- pragma foreign_proc("Java",
+	time__c_times(Ret::out, _Ut::out, _St::out, _CUt::out,
+                               _CSt::out, _IO0::di, _IO::uo),
+	[will_not_call_mercury, promise_pure, tabled_for_io],
+"
+	// This method always returns -1 to indicate an inability to retrieve
+	// these values, since this is not supported by Java.
+
+	Ret = -1;
+").
+
 %-----------------------------------------------------------------------------%
 
 time__clk_tck = Ret :-
@@ -339,12 +370,20 @@
 	Ret = -1;
 #endif
 }").
+time__c_clk_tck = -1.	% default is to throw an exception.
+
 :- pragma foreign_proc("C#", time__clk_tck = (Ret::out),
 	[will_not_call_mercury, promise_pure],
 "{
 	// TicksPerSecond is guaranteed to be 10,000,000
 	Ret = (int) System.TimeSpan.TicksPerSecond;
 }").
+:- pragma foreign_proc("Java", time__clk_tck = (Ret::out),
+	[will_not_call_mercury, promise_pure],
+"
+	// Java only supports millisecond precision.
+	Ret = 1000;
+").
 
 %-----------------------------------------------------------------------------%
 
@@ -375,6 +414,12 @@
 "{
 	Ret = System.DateTime.UtcNow;
 }").
+:- pragma foreign_proc("Java",
+	time__c_time(Ret::out, _IO0::di, _IO::uo),
+	[will_not_call_mercury, promise_pure, tabled_for_io],
+"
+	Ret = new java.util.Date();
+").
 
 :- pred time__time_t_is_invalid(time_t_rep).
 :- mode time__time_t_is_invalid(in) is semidet.
@@ -391,7 +436,12 @@
 "{
 	SUCCESS_INDICATOR = false;
 }").
-
+:- pragma foreign_proc("Java",
+	time__time_t_is_invalid(_Val::in),
+	[will_not_call_mercury, promise_pure],
+"
+	succeeded = false;
+").
 
 
 %-----------------------------------------------------------------------------%
@@ -418,6 +468,12 @@
 	span = T1 - T0;
 	Diff = span.TotalSeconds;
 }").
+:- pragma foreign_proc("Java",
+	time__c_difftime(T1::in, T0::in, Diff::out),
+	[will_not_call_mercury, promise_pure],
+"
+	Diff = (double) (T1.getTime() - T0.getTime()) / 1000;
+").
 
 %-----------------------------------------------------------------------------%
 
@@ -483,6 +539,52 @@
 		N = 0;
 	}
 }").
+:- pragma foreign_proc("Java",
+	time__c_localtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
+		Min::out, Sec::out, YD::out, WD::out, N::out),
+	[will_not_call_mercury, promise_pure],
+"
+	java.util.GregorianCalendar gc = new java.util.GregorianCalendar();
+
+	gc.setTime(Time);
+	Yr = gc.get(java.util.Calendar.YEAR) - 1900;
+	Mnt = gc.get(java.util.Calendar.MONTH);
+	MD = gc.get(java.util.Calendar.DAY_OF_MONTH);
+	Hrs = gc.get(java.util.Calendar.HOUR_OF_DAY);
+	Min = gc.get(java.util.Calendar.MINUTE);
+	Sec = gc.get(java.util.Calendar.SECOND);
+	YD = gc.get(java.util.Calendar.DAY_OF_YEAR) - 1;
+
+	switch (gc.get(java.util.Calendar.DAY_OF_WEEK)) {
+		case java.util.Calendar.SUNDAY:
+			WD = 0;
+			break;
+		case java.util.Calendar.MONDAY:
+			WD = 1;
+			break;
+		case java.util.Calendar.TUESDAY:
+			WD = 2;
+			break;
+		case java.util.Calendar.WEDNESDAY:
+			WD = 3;
+			break;
+		case java.util.Calendar.THURSDAY:
+			WD = 4;
+			break;
+		case java.util.Calendar.FRIDAY:
+			WD = 5;
+			break;
+		case java.util.Calendar.SATURDAY:
+			WD = 6;
+			break;
+		default:
+			throw new RuntimeException(
+				"DAY_OF_WEEK undefined in time__c_local_time");
+			break;
+	}
+
+	N = gc.get(java.util.Calendar.DST_OFFSET) != 0 ? 1 : 0;
+"). % time__c_local_time
 
 
 %:- func time__gmtime(time_t) = tm.
@@ -539,6 +641,54 @@
 	// UTC time can never have daylight savings.
 	N = 0;
 }").
+:- pragma foreign_proc("Java",
+	time__c_gmtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
+		Min::out, Sec::out, YD::out, WD::out, N::out),
+	[will_not_call_mercury, promise_pure],
+"
+	java.util.GregorianCalendar gc =
+			new java.util.GregorianCalendar(
+			java.util.SimpleTimeZone.getTimeZone(""GMT""));
+
+	gc.setTime(Time);
+	Yr = gc.get(java.util.Calendar.YEAR) - 1900;
+	Mnt = gc.get(java.util.Calendar.MONTH);
+	MD = gc.get(java.util.Calendar.DAY_OF_MONTH);
+	Hrs = gc.get(java.util.Calendar.HOUR_OF_DAY);
+	Min = gc.get(java.util.Calendar.MINUTE);
+	Sec = gc.get(java.util.Calendar.SECOND);
+	YD = gc.get(java.util.Calendar.DAY_OF_YEAR) - 1;
+
+	switch (gc.get(java.util.Calendar.DAY_OF_WEEK)) {
+		case java.util.Calendar.SUNDAY:
+			WD = 0;
+			break;
+		case java.util.Calendar.MONDAY:
+			WD = 1;
+			break;
+		case java.util.Calendar.TUESDAY:
+			WD = 2;
+			break;
+		case java.util.Calendar.WEDNESDAY:
+			WD = 3;
+			break;
+		case java.util.Calendar.THURSDAY:
+			WD = 4;
+			break;
+		case java.util.Calendar.FRIDAY:
+			WD = 5;
+			break;
+		case java.util.Calendar.SATURDAY:
+			WD = 6;
+			break;
+		default:
+			throw new RuntimeException(
+				"DAY_OF_WEEK undefined in time__c_gmtime");
+			break;
+	}
+
+	N = gc.get(java.util.Calendar.DST_OFFSET) != 0 ? 1 : 0;
+"). % time__c_gmtime
 
 :- func int_to_maybe_dst(int) = maybe(dst).
 
@@ -598,6 +748,25 @@
 		new System.DateTime(Yr + 1900, Mnt + 1, MD, Hrs, Min, Sec);
 	Time = local_time.ToUniversalTime();
 }").
+:- pragma foreign_proc("Java",
+	time__c_mktime(Yr::in, Mnt::in, MD::in, Hrs::in, Min::in, Sec::in,
+		_YD::in, _WD::in, N::in, Time::out),
+	[will_not_call_mercury, promise_pure],
+"
+	java.util.GregorianCalendar gc = new java.util.GregorianCalendar(
+			Yr + 1900, Mnt, MD, Hrs, Min, Sec);
+
+	if (N == 0) {
+		gc.set(java.util.Calendar.DST_OFFSET, 0);
+	} else {
+		gc.set(java.util.Calendar.DST_OFFSET,
+				((java.util.SimpleTimeZone)
+				java.util.SimpleTimeZone.getDefault()).
+				getDSTSavings());
+	}
+
+	Time = gc.getTime();
+").
 
 :- func maybe_dst_to_int(maybe(dst)) = int.
 
--------------------------------------------------------------------------
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