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

2012-03-14 Thread Wolfgang Laun
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 lhor...@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] Problem with temporal operations spanning daylight to standard time

2012-03-13 Thread lhorton
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@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users