[m-rev.] For review: Bug fix for time library

James Goddard goddardjames at yahoo.com
Thu Jan 22 15:20:36 AEDT 2004


Estimated hours taken: 1
Branches: main

Bug fix for the library procedure time__c_mktime for the Java back-end.

library/time.m:
	Fixed a bug where time__c_mktime was crashing at runtime due to a
	ClassCastException for Java v1.4 only.  (See comment in new method
	getDSTSavings())


Index: time.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/time.m,v
retrieving revision 1.39
diff -u -d -r1.39 time.m
--- time.m	18 Dec 2003 01:12:44 -0000	1.39
+++ time.m	22 Jan 2004 04:13:27 -0000
@@ -733,9 +733,7 @@
 	// If the time we constructed is not in daylight savings time, but
 	// it should be, we need to subtract the DSTSavings.
 	if (N == 1 && gc.getTimeZone().inDaylightTime(Time) == false) {
-		Time.setTime(Time.getTime() -
-				((java.util.SimpleTimeZone) gc.getTimeZone()).
-				getDSTSavings());
+		Time.setTime(Time.getTime() - getDSTSavings(gc.getTimeZone()));
 		if (gc.getTimeZone().inDaylightTime(Time) == false) {
 			throw new RuntimeException(
 				""time__mktime: failed to correct for DST"");
@@ -745,14 +743,52 @@
 	// If the time we constructed is in daylight savings time, but
 	// should not be, we need to add the DSTSavings.
 	if (N == 0 && gc.getTimeZone().inDaylightTime(Time) == true) {
-		Time.setTime(Time.getTime() +
-				((java.util.SimpleTimeZone) gc.getTimeZone()).
-				getDSTSavings());
+		Time.setTime(Time.getTime() + getDSTSavings(gc.getTimeZone()));
 		if (gc.getTimeZone().inDaylightTime(Time) == true) {
 			throw new RuntimeException(
 				""time__mktime: failed to correct for DST"");
 		}
 	}
+").
+
+:- pragma foreign_code("Java",
+"
+/*
+** getDSTSavings():
+**	This method uses reflection to retrieve and call the getDSTSavings()
+**	method for a given TimeZone object.
+**
+**	The reason we do this is that for Java versions < 1.4, the
+**	TimeZone.getDSTSavings() method did not exist, but the
+**	SimpleTimeZone.getDSTSavings() method did, and the concrete instance of
+**	TimeZone used by GregorianCalender (which is what we use in this
+**	module) is a SimpleTimeZone.
+**	However, we can't just cast the TimeZone instance to SimpleTimeZone,
+**	because for Java versions >= 1.4, GregorianCalender no longer uses a
+**	SimpleTimeZone.  So in this case, what we really want is
+**	TimeZone.getDSTSavings(), but we can't just put that or the code won't
+**	compile for Java versions < 1.4.
+**
+**	Thus, the solution is to invoke the getDSTSavings() method using
+**	reflection, which will cover both cases.
+*/
+public static int
+getDSTSavings(java.util.TimeZone tz) {
+	try {
+		// Simulate
+		//	return tz.getDSTSavings()
+		// using reflection.
+
+		return ((java.lang.Integer) (tz.getClass().
+				getMethod(""getDSTSavings"", null).
+				invoke(tz, null))).intValue();
+	}
+	catch (java.lang.Exception e) {
+		throw new java.lang.RuntimeException(
+				""time__c_mktime: Failed to locate "" +
+				""getDSTSavings() method."");
+	}
+}
 ").
 
 :- 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