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

Calculate medium timestamps properly

上级 97c8bcce
......@@ -100,19 +100,33 @@ class AggregateDataMedian extends AggregateData {
case Value.TIMESTAMP: {
ValueTimestamp ts0 = (ValueTimestamp) v0.convertTo(Value.TIMESTAMP),
ts1 = (ValueTimestamp) v1.convertTo(Value.TIMESTAMP);
return ValueTimestamp.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay((DateTimeUtils.absoluteDayFromDateValue(ts0.getDateValue())
+ DateTimeUtils.absoluteDayFromDateValue(ts1.getDateValue())) / 2),
(ts0.getTimeNanos() + ts1.getTimeNanos()) / 2);
long dateSum = DateTimeUtils.absoluteDayFromDateValue(ts0.getDateValue())
+ DateTimeUtils.absoluteDayFromDateValue(ts1.getDateValue());
long nanos = (ts0.getTimeNanos() + ts1.getTimeNanos()) / 2;
if ((dateSum & 1) != 0) {
nanos += (DateTimeUtils.NANOS_PER_DAY / 2);
if (nanos >= DateTimeUtils.NANOS_PER_DAY) {
nanos -= DateTimeUtils.NANOS_PER_DAY;
dateSum++;
}
}
return ValueTimestamp.fromDateValueAndNanos(DateTimeUtils.dateValueFromAbsoluteDay(dateSum / 2), nanos);
}
case Value.TIMESTAMP_TZ: {
ValueTimestampTimeZone ts0 = (ValueTimestampTimeZone) v0.convertTo(Value.TIMESTAMP_TZ),
ts1 = (ValueTimestampTimeZone) v1.convertTo(Value.TIMESTAMP_TZ);
return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay((DateTimeUtils.absoluteDayFromDateValue(ts0.getDateValue())
+ DateTimeUtils.absoluteDayFromDateValue(ts1.getDateValue())) / 2),
(ts0.getTimeNanos() + ts1.getTimeNanos()) / 2,
(short) ((ts0.getTimeZoneOffsetMins() + ts1.getTimeZoneOffsetMins()) / 2));
long dateSum = DateTimeUtils.absoluteDayFromDateValue(ts0.getDateValue())
+ DateTimeUtils.absoluteDayFromDateValue(ts1.getDateValue());
long nanos = (ts0.getTimeNanos() + ts1.getTimeNanos()) / 2;
if ((dateSum & 1) != 0) {
nanos += (DateTimeUtils.NANOS_PER_DAY / 2);
if (nanos >= DateTimeUtils.NANOS_PER_DAY) {
nanos -= DateTimeUtils.NANOS_PER_DAY;
dateSum++;
}
}
return ValueTimestampTimeZone.fromDateValueAndNanos(DateTimeUtils.dateValueFromAbsoluteDay(dateSum / 2),
nanos, (short) ((ts0.getTimeZoneOffsetMins() + ts1.getTimeZoneOffsetMins()) / 2));
}
default:
// Just return first
......
......@@ -42,7 +42,10 @@ public class DateTimeUtils {
*/
public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
private static final long NANOS_PER_DAY = MILLIS_PER_DAY * 1000000;
/**
* The number of nanoseconds per day.
*/
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;
......
......@@ -584,6 +584,17 @@ select median(v) from test;
> ---------------------
> 2000-01-15 15:00:00.0
delete from test;
> update count: 5
insert into test values ('2000-01-20 20:00:00'), ('2000-01-21 20:00:00');
> update count: 2
select median(v) from test;
> MEDIAN(V)
> ---------------------
> 2000-01-21 08:00:00.0
drop table test;
> ok
......@@ -619,5 +630,16 @@ select median(v) from test;
> ------------------------
> 2000-01-15 15:00:00.0+03
delete from test;
> update count: 5
insert into test values ('2000-01-20 20:00:00+10'), ('2000-01-21 20:00:00-09');
> update count: 2
select median(v) from test;
> MEDIAN(V)
> ---------------------------
> 2000-01-21 08:00:00.0+00:30
drop table test;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论