Fix incorrect date type value when timezone is set (#97)

Signed-off-by: birdstorm <samuelwyf@hotmail.com>
This commit is contained in:
birdstorm 2020-10-30 14:18:45 +08:00 committed by GitHub
parent 5f3d9f5aa4
commit 1d8e58a9d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 9 deletions

View File

@ -197,7 +197,7 @@ public class TiBlockColumnVector extends TiColumnVector {
int month = (int) (ym % 13);
int day = (int) (ymd & ((1 << 5) - 1));
LocalDate date = new LocalDate(year, month, day);
return Math.floorDiv(date.toDate().getTime(), AbstractDateTimeType.MILLS_PER_DAY);
return ((DateType) type).getDays(date);
}
/**
* Returns the long type value for rowId. The return value is undefined and can be anything, if

View File

@ -135,7 +135,7 @@ public class TiChunkColumnVector extends TiColumnVector {
}
if (this.type instanceof DateType) {
LocalDate date = new LocalDate(year, month, day);
return Math.floorDiv(date.toDate().getTime(), AbstractDateTimeType.MILLS_PER_DAY);
return ((DateType) type).getDays(date);
} else if (type instanceof DateTimeType || type instanceof TimestampType) {
// only return microsecond from epoch.
Timestamp ts =

View File

@ -30,7 +30,6 @@ import org.tikv.common.exception.InvalidCodecFormatException;
import org.tikv.common.meta.TiColumnInfo.InternalTypeHolder;
public abstract class AbstractDateTimeType extends DataType {
public static long MILLS_PER_DAY = 3600L * 24 * 1000;
AbstractDateTimeType(InternalTypeHolder holder) {
super(holder);
@ -61,10 +60,7 @@ public abstract class AbstractDateTimeType extends DataType {
// nearest
// value which is 0001-01-01.
if (extendedDateTime == null) {
Timestamp ts =
DateTimeCodec.createExtendedDateTime(getTimezone(), 1, 1, 1, 0, 0, 0, 0).toTimeStamp();
// by dividing 1000 on milliseconds, we have eliminated fraction part of ts
return ts.getTime() / 1000 * 100000 + ts.getNanos() / 1000;
extendedDateTime = DateTimeCodec.createExtendedDateTime(getTimezone(), 1, 1, 1, 0, 0, 0, 0);
}
Timestamp ts = extendedDateTime.toTimeStamp();
return ts.getTime() / 1000 * 1000000 + ts.getNanos() / 1000;

View File

@ -19,6 +19,7 @@ package org.tikv.common.types;
import java.sql.Date;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.tikv.common.codec.Codec.DateCodec;
import org.tikv.common.codec.CodecDataInput;
@ -28,6 +29,7 @@ import org.tikv.common.exception.ConvertOverflowException;
import org.tikv.common.meta.TiColumnInfo;
public class DateType extends AbstractDateTimeType {
private static final LocalDate EPOCH = new LocalDate(0);
public static final DateType DATE = new DateType(MySQLType.TypeDate);
public static final MySQLType[] subTypes = new MySQLType[] {MySQLType.TypeDate};
@ -90,6 +92,16 @@ public class DateType extends AbstractDateTimeType {
return "DATE";
}
public int getDays(LocalDate d) {
// count how many days from EPOCH
int days = Days.daysBetween(EPOCH, d).getDays();
// if the timezone has negative offset, minus one day.
if (getTimezone().getOffset(0) < 0) {
days -= 1;
}
return days;
}
/** {@inheritDoc} */
@Override
protected Long decodeNotNull(int flag, CodecDataInput cdi) {
@ -98,8 +110,8 @@ public class DateType extends AbstractDateTimeType {
if (date == null) {
return null;
}
// return how many days from EPOCH
return Math.floorDiv(date.toDate().getTime(), AbstractDateTimeType.MILLS_PER_DAY);
return (long) getDays(date);
}
@Override