[rules-users] Problem with temporal operations spanning daylight to standard time

Wolfgang Laun wolfgang.laun at gmail.com
Wed Mar 14 05:07:03 EDT 2012


Designations like "2012-03-10 13:30:00.000" are just labels we attach
according to several conventions to the points in time (PiT) which are
a continuously numbered sequence of ticks (of a certain length),
starting at an arbitrary point in time. If you select two PiTs this
way and then calculate the number of ticks between them, you must make
sure that the PiTs have been selected by a suitable convention, i.e.,
one that isn't ambiguous and doesn't have gaps.

Such conventions are called Time Zones, and many of these don't pass
the aforementioned requirements. The new Date you create on your
system follows the convention adopted for your host's time and date,
and your cunning sysadmin has chosen a setting to conform to
Californian usage.

You have several options.

You can use the (deprectated) API of java.util.Date to create PiTs
using a clean mapping, e.g., the one provided by UTC.

       Date utc = new Date( Date.UTC( 2012-1900, 3-1, 24, 0, 0, 0 ) );

Alternatively and avoiding deprecated methods and with a cleaner
interface, declare

    private static Calendar calUTC =
       new GregorianCalendar( TimeZone.getTimeZone("UTC") );
    public static Date utcDate(int year, int month, int day ){
        calUTC.set( year-1900, month-1, day );
        return calUTC.getTime();
    }

and call it like this:

     Date utc = utcDate( 2012, 3, 24 );

Cheers
Wolfgang



On 13/03/2012, lhorton <LHorton at abclegal.com> wrote:
> Most of the USA went from Standard Time to Daylight Time this past weekend.
> We use some of the temporal operations in our rules, mainly to do
> calculations of date differences by whole days, and some of the calculations
> are wrong.  The ones in error involve comparing dates where one is standard
> time and one is daylight savings time.  I wrote a small test case to prove
> this.
>
> I have a simple Person class:
> public class Person  {
>
> 	private Date birthdate;
> 	private int status;
>
> 	public Date getBirthdate() {
> 		return birthdate;
> 	}
>
> 	public void setBirthdate(Date birthdate) {
> 		this.birthdate = birthdate;
> 	}
>
> 	public int getStatus() {
> 		return status;
> 	}
>
> 	public void setStatus(int status) {
> 		this.status = status;
> 	}
> }
>
> and a simple drl file:
>
> package com.drools.resources;
>
> import com.drools.person.Person;
> import java.util.Date;
> import java.util.Calendar;
>
> global Long now
>
> rule "Birthday Rule"
> dialect "mvel"
> when
> 	$person : Person(birthdate != null)
> 	Date($bDate : time before[3d] now) from $person.birthdate
> then
> 	$person.setStatus(3);
> end
>
> rule "Debug Birthday Rule"
> dialect "mvel"
> when
> 	$person : Person(birthdate != null)
> then
> 	System.out.println("now is " + new Date(now));
> 	System.out.println("birthdate is " + $person.getBirthdate());
> end
>
> and two tests:
> 	@Test
> 	public void testTemporalJanuary() throws Exception {
> 		KnowledgeBase base =
> createKnowledgeBaseFromRulesFile("src/com/drools/resources/temporal.drl");
> 		StatelessKnowledgeSession kSession =
> createStatelessKnowledgeSession(base);
>
> 		// test january - both dates are standard time
> 		Date now = new Date(2012-1900, 00, 13);
> 		kSession.getGlobals().set("now", now.getTime());
> 		Person p = new Person();
> 		p.setStatus(0);
> 		p.setBirthdate(new Date(2012-1900, 00, 10));
> 		kSession.execute(p);
> 		assertTrue(p.getStatus() == 3);
>
> 	}
>
> 	@Test
> 	public void testTemporalMarch() throws Exception {
> 		KnowledgeBase base =
> createKnowledgeBaseFromRulesFile("src/com/drools/resources/temporal.drl");
> 		StatelessKnowledgeSession kSession =
> createStatelessKnowledgeSession(base);
>
> 		// test March: one day standard, the other is daylight
> 		Date now = new Date(2012-1900, 02, 13);
> 		kSession.getGlobals().set("now", now.getTime());
> 		Person p = new Person();
> 		p.setStatus(0);
> 		p.setBirthdate(new Date(2012-1900, 02, 10));
> 		kSession.execute(p);
> 		assertTrue(p.getStatus() == 3);
>
>
> 	}
>
>
> the first test (testTemporalJanuary) compares January 13 to January 10, and
> it passes (matches the before[3d] condition).
>
> the second test (testTemporalMarch, which is the same except for using March
> instead of January) fails.
>
> The output of the debug rule for these tests is:
>
>    now is Fri Jan 13 00:00:00 PST 2012
>    birthdate is Tue Jan 10 00:00:00 PST 2012
>
>    now is Tue Mar 13 00:00:00 PDT 2012
>    birthdate is Sat Mar 10 00:00:00 PST 2012
>
>
>
>
> --
> View this message in context:
> http://drools.46999.n3.nabble.com/Problem-with-temporal-operations-spanning-daylight-to-standard-time-tp3823618p3823618.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>



More information about the rules-users mailing list