[
https://issues.apache.org/jira/browse/LANG-312?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12462483
]
Hayo commented on LANG-312:
---------------------------
Thanks for your answer, Henri!
You are right, it is not really a bug in the DateFormatUtils. It was a lack in
understanding the Timezone concept by me and a probably misconception of
java.sql.Date by Sun. I have a proposal at the end, to avoid falling in this
trap.
TimeZone.getDefault().getID() and System.getProperty( "user.timezone" ) are
"Europe/Berlin" on all systems we use. Timezone parameter we used for
DateFormatUtils.format is "CET". The summer times from 1945 to 1949 obviously
is where CET and "Europe/Berlin" differ.
Example:
Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("CET"),
Locale.GERMANY);
cal.set(1947, 7, 2);
Now cal.getTimeInMillis(); is not equal (new java.sql.Date(47, 7
,2).getTime()); for default Europe/Berlin
If the Java vm is started with parameter -Duser.timezone=Europe/Berlin,
everybody should be able to reproduce the effect with my code above. (We now
set -Duser.timezone=CET to avoid it in existing deployment).
I admit that with java.util.Date the issue is simply our fault. But, in my
opinion with java.sql.Date the function should be improved. Our buggy real life
code uses java.sql.Date that is returned from the JDBC 2.0 driver for DB2 in a
ResultSet, which is a very common thing to do.
>From the documentation of java.sql.Date.
"public Date(long date)
Constructs a Date object using the given milliseconds time value. If the given
milliseconds value contains time information, the driver will set the time
components to the time in the default time zone (the time zone of the Java
virtual machine running the application) that corresponds to zero GMT. "
So the local time of a java.sql.Date is always 00:00:00.
My proposal for format () is:
if (date instanceof java.sql.Date) {
Calendar cal = GregorianCalendar.getInstance(timeZone, locale);
cal.set(1900 + date.getYear(), date.getMonth(), date.getDate());
} else {
// construct Calendar as already implemented
}
Then there is no way to get the wrong sql date any more. I currently do not see
any drawbacks of this solution.
Regards,
Hayo
> DateFormatUtils.format with Timezone parameter "CET" produces wrong date in
> summer time 1945 to 1949
> ----------------------------------------------------------------------------------------------------
>
> Key: LANG-312
> URL: https://issues.apache.org/jira/browse/LANG-312
> Project: Commons Lang
> Issue Type: Bug
> Affects Versions: 2.1, 2.2
> Environment: IBM Java 1.4.2, Sun Java 1.4.2, Windows XP, SuSE Linux
> Enterprise 9, German systems, at winter time
> Reporter: Hayo
>
> DateFormatUtils.format(dt, "dd/MM/yyyy", Timezone.getTimezone("CET"),
> Locale.GERMANY); returns the date of the day before during summer time of the
> years 1945 to 1949. The problem was detected on a system running in
> Locale.GERMANY, current time "CET", JDK 1.4.2.
> The problem does not occur with the call DateFormatUtils.format(dt,
> "dd/MM/yyyy"); which presumably uses the system defaults. These are likely to
> be the same as the parameters i have passed.
> The following code snippet demonstrates the problem:
> for (int year = 0; year < 150; year ++) {
> for (int month = 0; month <= 11; month ++) {
> for (int day = 1; day <= 28; day ++) {
> java.sql.Date dt = new java.sql.Date(year, month, day);
> // or java.util.Date
> String def = DateFormatUtils.format(dt, "dd/MM/yyyy");
> String cet = DateFormatUtils.format(dt, "dd/MM/yyyy",
> Timezone.getTimezone("CET"), Locale.GERMANY);
>
> if (!cet.equals(def)) {
> System.err.println(dt.toLocaleString() + " Default: "
> + def + " CET: " + cet);
> }
> }
> }
> }
>
> Output:
> ------
>
> 03.04.1945 00:00:00 Default: 03/04/1945 CET:02/04/1945
> [...]
> 18.11.1945 00:00:00 Default: 18/11/1945 CET:17/11/1945
> 15.04.1946 00:00:00 Default: 15/04/1946 CET:14/04/1946
> [...]
> 07.10.1946 00:00:00 Default: 07/10/1946 CET:06/10/1946
> 07.04.1947 00:00:00 Default: 07/04/1947 CET:06/04/1947
> [...]
> 05.10.1947 00:00:00 Default: 05/10/1947 CET:04/10/1947
> 19.04.1948 00:00:00 Default: 19/04/1948 CET:18/04/1948
> [...]
> 03.10.1948 00:00:00 Default: 03/10/1948 CET:02/10/1948
> 11.04.1949 00:00:00 Default: 11/04/1949 CET:10/04/1949
> [...]
> 02.10.1949 00:00:00 Default: 02/10/1949 CET:01/10/1949
> This seems to be during the summer time of 1949 to 1945 in Berlin, and only
> in Berlin. Setting the Locale to any other value has no effect on that. So i
> ask myself, what results other central european users get. Setting the
> Timezone to "GMT+2" extracts exactly the high summer times in 1945 and 1947
> (MEHSZ). (See below for list of summer times).
> I could guess that some calendar calculations work with different libraries
> that have different summer time maps (java.util.Date vs. Calendar). This
> might depend on my environment, so this task should be tested by others (with
> their local Timezone).
> The API documentation does not clearly state what effect the Timezone/Locale
> parameters should have.
> In my strong opinion at least dates passed as java.sql.Date should not be
> normalized to summer/standard time. A date is a date! For java.util.Date the
> date recalculation behaviour should be mentioned in the docs, if it is really
> intended this way by design.
> ===============================================================================
> These where the actual summer times in Germany
> (http://www.ptb.de/de/org/4/44/441/salt.htm
>
> http://de.wikipedia.org/wiki/Hochsommerzeit#Mitteleurop.C3.A4ische_Sommerzeit)
> a) Summer time, Advance to CET (GMT+1): 1 hour (GMT+2)
> 1916-04-30 23:00:00 CET until 1916-10-01 1:00:00 CEST
> 1917-04-16 2:00:00 CET until 1917-09-17 3:00:00 CEST
> 1918-04-15 2:00:00 CET until 1918-09-16 3:00:00 CEST
> 1919 until 1939: No Summer time
> 1940-04-01 2:00:00 CET until 1942-11-02 3:00:00 CEST
> 1943-03-29 2:00:00 CET until 1943-10-04 3:00:00 CEST
> 1944-04-03 2:00:00 CET until 1944-10-02 3:00:00 CEST
> 1945-04-02 2:00:00 CET until 1945-09-16 2:00:00 CEST
> Special: Berlin and sowjet occupied zone:
> (1945-05-24) 2:00:00 CET until 1945-11-18 3:00:00 CEST
> (1945-05-24) 3:00:00 CET until 1945-09-24 2:00:00 MEHSZ
> 1946-04-14 2:00:00 CET until 1946-10-07 3:00:00 CEST
> 1947-04-06 3:00:00 CET until 1947-10-05 3:00:00 CEST
> 1948-04-18 2:00:00 CET until 1948-10-03 3:00:00 CEST
> 1949-04-10 2:00:00 CET until 1949-10-02 3:00:00 CEST
> b) High summer time, Advance to CET: 2 hours (GMT+3)
> 1947-05-11 3:00:00 CEST until 1947-06-29 3:00:00 MEHSZ
> c) From 1950 to 1979 no Summer times
> d) 1980 to now (most of central europe)
> 1980-04-06 2:00:00 CET until 1980-09-28 3:00:00 CEST
> ...
> ongoing until today
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]