提交 aa806abe authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Do not use Calender for ValueTimestampTimeZone comparison

上级 bbbd555d
......@@ -921,19 +921,6 @@ public class DateTimeUtils {
return new Date(millis);
}
/**
* Convert an encoded date value to millis, using the supplied timezone.
*
* @param tz the timezone
* @param dateValue the date value
* @return the date
*/
public static long convertDateValueToMillis(TimeZone tz, long dateValue) {
return getMillis(tz, yearFromDateValue(dateValue),
monthFromDateValue(dateValue), dayFromDateValue(dateValue), 0,
0, 0, 0);
}
/**
* Convert an encoded date-time value to millis, using the supplied timezone.
*
......
......@@ -219,34 +219,31 @@ public class ValueTimestampTimeZone extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueTimestampTimeZone t = (ValueTimestampTimeZone) o;
// We are pretending that the dateValue is in UTC because that gives us
// a stable sort even if the DST database changes.
// convert to minutes and add timezone offset
long a = DateTimeUtils.convertDateValueToMillis(
DateTimeUtils.UTC, dateValue) /
(1000L * 60L);
long ma = timeNanos / (1000L * 1000L * 1000L * 60L);
a += ma;
a -= timeZoneOffsetMins;
// convert to minutes and add timezone offset
long b = DateTimeUtils.convertDateValueToMillis(
DateTimeUtils.UTC, t.dateValue) /
(1000L * 60L);
long mb = t.timeNanos / (1000L * 1000L * 1000L * 60L);
b += mb;
b -= t.timeZoneOffsetMins;
// compare date
int c = Long.compare(a, b);
if (c != 0) {
return c;
// Maximum time zone offset is +/-18 hours so difference in days between local
// and UTC cannot be more than one day
long daysA = DateTimeUtils.absoluteDayFromDateValue(dateValue);
long timeA = timeNanos - timeZoneOffsetMins * 60_000_000_000L;
if (timeA < 0) {
timeA += DateTimeUtils.NANOS_PER_DAY;
daysA--;
} else if (timeA >= DateTimeUtils.NANOS_PER_DAY) {
timeA -= DateTimeUtils.NANOS_PER_DAY;
daysA++;
}
long daysB = DateTimeUtils.absoluteDayFromDateValue(t.dateValue);
long timeB = t.timeNanos - t.timeZoneOffsetMins * 60_000_000_000L;
if (timeB < 0) {
timeB += DateTimeUtils.NANOS_PER_DAY;
daysB--;
} else if (timeB >= DateTimeUtils.NANOS_PER_DAY) {
timeB -= DateTimeUtils.NANOS_PER_DAY;
daysB++;
}
int cmp = Long.compare(daysA, daysB);
if (cmp != 0) {
return cmp;
}
// compare time
long na = timeNanos - (ma * 1000L * 1000L * 1000L * 60L);
long nb = t.timeNanos - (mb * 1000L * 1000L * 1000L * 60L);
return Long.compare(na, nb);
return Long.compare(timeA, timeB);
}
@Override
......
......@@ -126,21 +126,27 @@ public class TestTimeStampWithTimeZone extends TestBase {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-01 12:00:00.00+00:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 12:00:01.00+01:15");
int c = a.compareTo(b, null);
assertEquals(c, 1);
assertEquals(1, c);
c = b.compareTo(a, null);
assertEquals(-1, c);
}
private void test3() {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-02 00:00:02.00+01:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 23:00:01.00+00:15");
int c = a.compareTo(b, null);
assertEquals(c, 1);
assertEquals(1, c);
c = b.compareTo(a, null);
assertEquals(-1, c);
}
private void test4() {
ValueTimestampTimeZone a = ValueTimestampTimeZone.parse("1970-01-02 00:00:01.00+01:15");
ValueTimestampTimeZone b = ValueTimestampTimeZone.parse("1970-01-01 23:00:01.00+00:15");
int c = a.compareTo(b, null);
assertEquals(c, 0);
assertEquals(0, c);
c = b.compareTo(a, null);
assertEquals(0, c);
}
private void test5() throws SQLException {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论