提交 8b16b1f2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Some timestamps with timezone were not converted correctly.

上级 2c65762f
......@@ -19,7 +19,11 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Sequences with cache size smaller than 0 did not work correctly.
<ul><li>Some timestamps with timezone were not converted correctly.
For example, in the PST timezone, the timestamp 2011-10-26 08:00:00Z was converted to
2011-10-25 25:00:00 instead of 2011-10-26 01:00:00.
Depending on the database operation, this caused subsequent error.
</li><li>Sequences with cache size smaller than 0 did not work correctly.
</li><li>Issue 356: for Blob objects, InputStream.skip() returned 0,
causing EOFException in Blob.getBytes(.., ..).
</li><li>Updateable result sets: if the value is not set when inserting a new row,
......
......@@ -26,6 +26,9 @@ import org.h2.value.ValueTimestamp;
/**
* This utility class contains time conversion functions.
* <p>
* Date value: a bit field with bits for the year, month, and day.
* Absolute day: the day number (0 means 1970-01-01).
*/
public class DateTimeUtils {
......@@ -34,7 +37,7 @@ public class DateTimeUtils {
*/
public static final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000L;
private static final long NANOS_PER_DAY = MILLIS_PER_DAY * 1000000;
public static final long NANOS_PER_DAY = MILLIS_PER_DAY * 1000000;
private static final int SHIFT_YEAR = 9;
private static final int SHIFT_MONTH = 5;
......@@ -325,10 +328,10 @@ public class DateTimeUtils {
}
/**
* Calculate the milliseconds for the given date and time in the specified
* timezone.
* Calculate the milliseconds since 1970-01-01 (UTC) for the given date and
* time (in the specified timezone).
*
* @param tz the timezone
* @param tz the timezone of the parameters
* @param year the absolute year (positive or negative)
* @param month the month (1-12)
* @param day the day (1-31)
......@@ -336,7 +339,7 @@ public class DateTimeUtils {
* @param minute the minutes (0-59)
* @param second the number of seconds (0-59)
* @param millis the number of milliseconds
* @return the number of milliseconds
* @return the number of milliseconds (UTC)
*/
public static long getMillis(TimeZone tz, int year, int month, int day, int hour, int minute, int second, int millis) {
try {
......
......@@ -151,8 +151,10 @@ public class ValueTimestamp extends Value {
minute -= hour * 60;
long millis = DateTimeUtils.getMillis(tz, year, month, day, hour, minute, (int) second, (int) ms);
ms = DateTimeUtils.convertToLocal(new Date(millis), Calendar.getInstance(TimeZone.getTimeZone("UTC")));
dateValue = DateTimeUtils.dateValueFromDate(ms);
nanos += (ms - DateTimeUtils.absoluteDayFromDateValue(dateValue) * DateTimeUtils.MILLIS_PER_DAY) * 1000000;
long mpd = DateTimeUtils.MILLIS_PER_DAY;
long absoluteDay = (ms >= 0 ? ms : ms - mpd + 1) / mpd;
ms -= absoluteDay * mpd;
nanos += ms * 1000000;
}
}
return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
......
......@@ -52,6 +52,7 @@ public class TestDate extends TestBase {
testValueDate();
testValueTime();
testValueTimestamp();
testValueTimestampWithTimezone();
testValidDate();
testAbsoluteDay();
testCalculateLocalMillis();
......@@ -175,6 +176,21 @@ public class TestDate extends TestBase {
convertTo(Value.DATE).getString());
}
private void testValueTimestampWithTimezone() {
for (int m = 1; m <= 12; m++) {
for (int d = 1; d <= 28; d++) {
for (int h = 0; h <= 23; h++) {
String s = "2011-" + (m < 10 ? "0" : "") + m + "-" + (d < 10 ? "0" : "") + d + " " +
(h < 10 ? "0" : "") + h + ":00:00";
ValueTimestamp ts = ValueTimestamp.parse(s + "Z");
String s2 = ts.getString();
ValueTimestamp ts2 = ValueTimestamp.parse(s2);
assertEquals(ts.getString(), ts2.getString());
}
}
}
}
private void testValueTimestamp() {
assertEquals("2001-02-03 04:05:06.0", ValueTimestamp.get(
Timestamp.valueOf("2001-02-03 04:05:06")).getString());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论