Re: how does cayenne handle java.util.date values ?

2006-12-11 Thread Andrus Adamchik
Yeah, daylight saving time is tricky... Though the Date object still  
stores information about the timezone. I am surprised the driver  
doesn't account for it. Here is a few options that you have:


1. [the simplest] If you can redesign your database, I'd suggest  
storing dates as long numbers.
2. Normalize dates as pseudo-UTC (i.e. subtracting an absolute  
difference with UTC, that should take into account the daylight  
saving time):


Calendar cal1 = new GregorianCalendar();
cal1.setTime(date1);
int offsetMinutes = -(cal1.get(Calendar.ZONE_OFFSET) + cal1.get 
(Calendar.DST_OFFSET)) / (60 * 1000);


But again, I am surprised that driver doesn't do that for you - may  
require more research with your DB...


Andrus


On Dec 8, 2006, at 5:58 PM, Lothar Krenzien wrote:

Hi,

because I didn't solved the problems of my previous posts I've  
tried to create another demo. Basicly I have the following  
situation. I get an xml file (via a servlet) which contains a comma- 
separated list of values (for example energy values) and a start  
date. So the file could looks like  :


startDate28.10.2006 22:14:28/startDate
valueList0.2 , 0.5 , 0.7, 0.9/valueList

The first entry should be aligned to the last quarter before (!)  
the startDate. And then I have to iterate over the value list and  
align each value to the next quarter. The result should looks like :


28.10.2006 22:00 = 0.2
28.10.2006 22:15 = 0.5
28.10.2006 22:30 = 0.7
28.10.2006 22:45 = 0.9

Even if the startDate has always the format dd.MM. hh:mm it  
could represents  a different timezone. Let's say Asia/Seoul.


timezone = TimeZone.getTimeZone(Asia/Seoul);
dateFormat = new SimpleDateFormat(dd.MM. HH:mm:ss);
dateFormat.setTimeZone(timezone);
parsedDate = dateFormat.parse(startDate);

My problem now is, when I try to create a cayenne Tbl* object and  
set the date value in it - the following value is stored in the  
database Sat Oct 28 15:18:48 CEST 2006. But I would like to have  
Sat Oct 28 22:18:48 CEST 2006. I think it's because  
java.util.Date just stores the time in UTC and converts it  
transparently to the default timezone.


Of course I can get a workaround for it. But the major problem for  
me is the break in time during the change from summer- to  
wintertime (the clock is turned back by 1h).  In germay the clock  
changes from 3:00 a.m. to 2:00 a.m. That courses that when I  
proceed the value for 2:45 a.m the next value will be aligned to  
2:00 a.m again. But in Korea there is no summer- or wintertime so  
the value should be aligned to 3:00 a.m..


Generally that's not a problem because the timezone has a method  
inDaylightTime() so that I know when the change was happen and can  
skipp the unneeded values.
But as I just said, in Korea there is no daylighttime and thus no  
need to skipp the values. But Java converts the (korean) date value  
into a date value for the default timezone (germany here) and so I  
have the values between 2:00 a.m and 3.00 a.m. twice. And that's  
not allowed by the database.


When I convert the date back into a string using

dateFormat = new SimpleDateFormat(-MM- 
dd HH:mm:ss.SSS, );

dateFormat.setTimeZone(timezone);
formattedDate = dateFormat.format(valueDate);

I get the correct date string back.
For me it looks like that cayenne (or maybe the jdbc driver) should  
consider the timezone for a date.
I've provided two samples to illustrate what I mean. The first  
small sample shows how cayenne stores date values. The second  
sample shows the exception during the change in daylight time.


It would be nice if someone could try it out and could give a  
comment on it.


Thanks, Lothar

 the database tables  
-- 
-

/*
CREATE TABLE [dbo].[tblEfficiencyBlock] (
[efficiencyBlockId] [int] IDENTITY (1, 1) NOT NULL ,
[serialNumber] [varchar] (50) COLLATE Latin1_General_CI_AS NULL

) ON [PRIMARY]
GO


CREATE TABLE [dbo].[tblEffBlockData] (
[effBlockDataId] [int] IDENTITY (1, 1) NOT NULL ,
[efficiencyBlockId] [int] NOT NULL ,
[dataDate] [datetime] NOT NULL ,
[energyValue] [float] NOT NULL  
) ON [PRIMARY]
GO


CREATE UNIQUE
  INDEX [IX_tblEffblockdata_1] ON [dbo].[tblEffBlockData]  
([efficiencyBlockId], [dataDate])

WITH
DROP_EXISTING
ON [PRIMARY]

*/

/*
insert into tblEfficiencyBlock
(serialNumber)
values
('123456')
*/

-- the application code  


void doTest{
 energyValues = values.split(,);
 valueDate = adjustDataDate(timezone, parsedDate);

 for (String energyValue : energyValues) {
  if (timezone.inDaylightTime(valueDate)) { 
// skip some values
  }
 

Re: how does cayenne handle java.util.date values ?

2006-12-05 Thread Tore Halset

On Dec 5, 2006, at 14:26 , Lothar Krenzien wrote:

I've provided a simple demo class to show what I mean. I used Java  
5, cayenne 2.1 and jtds with MS SQL Server 2000.


Looks like the attachment are striped by the mail-list software.  
Could you copy/paste the code into the mail instead of attaching the  
java file?


 - Tore.


Re: how does cayenne handle java.util.date values ?

2006-12-05 Thread Andrus Adamchik
Attachments are stripped from the messages sent to the list, so I  
can't check your example. So let me ask you this - are you using  
Cayenne XMLEncoder/XMLDecoder? It won't handle the dates properly ...  
the rest of Cayenne will. If this doesn't help, could you please post  
a relevant code example inline (not as an attachment).


Andrus



On Dec 5, 2006, at 3:26 PM, Lothar Krenzien wrote:


Hi there,

I posted this yesterday again. But have just seen that I forgott  
the subject. Sorry for that
What I would like to know is how does cayenne handle java.util.date  
values ?


My problem is, that I have to import xml files with datetime values  
in it of different timezones. For example the file contains the  
following tag: date=30.11.2006 22:14:28. In my case it should  
represents a datetime value of german format (dd.MM. hh.mm.ss)  
BUT in local korean time. Korean time has an offset of +9h to GMT.  
So in GMT the time part is 13:14:28 and in german time (GMT +1h)  
it's 14:14:28. For some historical reasons I have to persistent  
the local datetime value (28.10.2006 22:14:28), but of course as  
date object instead of a string value.


When I now try to convert the string value into a date-object using  
standard java methods I will get an object which reflects GMT time.  
But when I try to print it out on a console it will be converted to  
local date (thus german date). And that date will be saved by  
cayenne in the database. So for me it looks like  that cayenne  
tries to call toString() on the date object and will get a  
recalculated date instead of the original date. If it's true I  
think it would be better to use a SimpleDateFormatter instance  
because than the you will get a correct datetime string.


I've provided a simple demo class to show what I mean. I used Java  
5, cayenne 2.1 and jtds with MS SQL Server 2000.


Thanks
Lothar





Re: how does cayenne handle java.util.date values ?

2006-12-05 Thread Lothar Krenzien

 -Ursprüngliche Nachricht-
 Von: cayenne-user@incubator.apache.org
 Gesendet: 05.12.06 14:33:50
 An: cayenne-user@incubator.apache.org
 Betreff: Re: how does cayenne handle java.util.date values ?


 On Dec 5, 2006, at 14:26 , Lothar Krenzien wrote:
 
  I've provided a simple demo class to show what I mean. I used Java  
  5, cayenne 2.1 and jtds with MS SQL Server 2000.
 
 Looks like the attachment are striped by the mail-list software.  
 Could you copy/paste the code into the mail instead of attaching the  
 java file?
 
   - Tore.
 

Ok here's the sample :

--

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class CayenneDateTest {


public static void main(String[] args) {
try {
System.out.println(litte java date parsing + formating 
sample);
doTest();
}
catch (Exception e) {
e.printStackTrace();
}
}

private static void doTest() throws Exception {
// the string value from the xml file
String dateValue = 28.10.2006 22:14:28;
TimeZone timeZone = TimeZone.getTimeZone(Asia/Seoul);
SimpleDateFormat dateFormat = new SimpleDateFormat(dd.MM. 
HH:mm:ss);
dateFormat.setTimeZone(timeZone);
Date parsedDate = dateFormat.parse(dateValue);
System.out.println(parsedDate: + parsedDate); // this will be 
stored by cayenne

dateFormat = new SimpleDateFormat(dd.MM. HH:mm:ss );
dateFormat.setTimeZone(timeZone);
String formattedDate = dateFormat.format(parsedDate);
System.out.println(formattedDate: + formattedDate);

dateFormat = new SimpleDateFormat(-MM-dd HH:mm:ss.SSS);
dateFormat.setTimeZone(timeZone);
formattedDate = dateFormat.format(parsedDate);
System.out.println(formattedDate: + formattedDate); // this 
is what I like to be stored by cayenne
}

private static void doImport() {
// this is a pseudo example how the real application does the 
db import

/*
String dataDate = 28.10.2006 22:14:28 ;
TimeZone timeZone = TimeZone.getTimeZone(Asia/Seoul);
SimpleDateFormat dateFormat = new SimpleDateFormat(dd.MM. 
HH:mm:ss);
dateFormat.setTimeZone(timeZone);
Date parsedDate = dateFormat.parse(dataDate);
TblImportEffBlockData importData = 
(TblImportEffBlockData)context.createAndRegisterNewObject(TblImportEffBlockData.class);
importData.setDataDate(parsedDate);
context.commitChanges();*/

/*
-- cayenne log output
INSERT INTO dbo.tblImportEffBlockData
(dataDate)

bind: '2006-10-28 15:14:28.0'
*/

/*
-- db table definition

CREATE TABLE [dbo].[tblImportEffBlockData] (
[importEffBlockDataId] [int] IDENTITY (1, 1) NOT NULL ,
[dataDate] [datetime] NOT NULL
) ON [PRIMARY]
GO
*/
}
}

--
__
Ein Herz für Kinder - Ihre Spende hilft! Aktion: www.deutschlandsegelt.de
Unser Dankeschön: Ihr Name auf dem Segel der 1. deutschen America's Cup-Yacht!