提交 18769b71 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add and use incrementDateValue() and decrementDateValue()

上级 850bee14
...@@ -1221,12 +1221,10 @@ public class DateTimeUtils { ...@@ -1221,12 +1221,10 @@ public class DateTimeUtils {
timeNanos -= correction; timeNanos -= correction;
if (timeNanos < 0) { if (timeNanos < 0) {
timeNanos += NANOS_PER_DAY; timeNanos += NANOS_PER_DAY;
dateValue = DateTimeUtils dateValue = decrementDateValue(dateValue);
.dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) - 1);
} else if (timeNanos >= NANOS_PER_DAY) { } else if (timeNanos >= NANOS_PER_DAY) {
timeNanos -= NANOS_PER_DAY; timeNanos -= NANOS_PER_DAY;
dateValue = DateTimeUtils dateValue = incrementDateValue(dateValue);
.dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) + 1);
} }
} }
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos, (short) offsetMins); return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos, (short) offsetMins);
...@@ -1320,6 +1318,63 @@ public class DateTimeUtils { ...@@ -1320,6 +1318,63 @@ public class DateTimeUtils {
return dateValue(y, m + 3, (int) d); return dateValue(y, m + 3, (int) d);
} }
/**
* Return the next date value.
*
* @param dateValue
* the date value
* @return the next date value
*/
public static long incrementDateValue(long dateValue) {
int year = yearFromDateValue(dateValue);
if (year == 1582) {
// Use slow way instead of rarely needed large custom code.
return dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) + 1);
}
int day = dayFromDateValue(dateValue);
if (day < 28) {
return dateValue + 1;
}
int month = monthFromDateValue(dateValue);
if (day < getDaysInMonth(year, month)) {
return dateValue + 1;
}
day = 1;
if (month < 12) {
month++;
} else {
month = 1;
year++;
}
return dateValue(year, month, day);
}
/**
* Return the previous date value.
*
* @param dateValue
* the date value
* @return the previous date value
*/
public static long decrementDateValue(long dateValue) {
int year = yearFromDateValue(dateValue);
if (year == 1582) {
// Use slow way instead of rarely needed large custom code.
return dateValueFromAbsoluteDay(absoluteDayFromDateValue(dateValue) - 1);
}
if (dayFromDateValue(dateValue) > 1) {
return dateValue - 1;
}
int month = monthFromDateValue(dateValue);
if (month > 1) {
month--;
} else {
month = 12;
year--;
}
return dateValue(year, month, getDaysInMonth(year, month));
}
/** /**
* Append a date to the string builder. * Append a date to the string builder.
* *
......
...@@ -62,7 +62,7 @@ public class ValueTimestamp extends Value { ...@@ -62,7 +62,7 @@ public class ValueTimestamp extends Value {
private ValueTimestamp(long dateValue, long timeNanos) { private ValueTimestamp(long dateValue, long timeNanos) {
this.dateValue = dateValue; this.dateValue = dateValue;
if (timeNanos < 0 || timeNanos >= 24L * 60 * 60 * 1000 * 1000 * 1000) { if (timeNanos < 0 || timeNanos >= DateTimeUtils.NANOS_PER_DAY) {
throw new IllegalArgumentException("timeNanos out of range " + timeNanos); throw new IllegalArgumentException("timeNanos out of range " + timeNanos);
} }
this.timeNanos = timeNanos; this.timeNanos = timeNanos;
...@@ -229,7 +229,7 @@ public class ValueTimestamp extends Value { ...@@ -229,7 +229,7 @@ public class ValueTimestamp extends Value {
long dv = dateValue; long dv = dateValue;
if (n2 >= DateTimeUtils.NANOS_PER_DAY) { if (n2 >= DateTimeUtils.NANOS_PER_DAY) {
n2 -= DateTimeUtils.NANOS_PER_DAY; n2 -= DateTimeUtils.NANOS_PER_DAY;
dv = DateTimeUtils.dateValueFromAbsoluteDay(DateTimeUtils.absoluteDayFromDateValue(dateValue) + 1); dv = DateTimeUtils.incrementDateValue(dv);
} }
return fromDateValueAndNanos(dv, n2); return fromDateValueAndNanos(dv, n2);
} }
......
...@@ -70,7 +70,7 @@ public class ValueTimestampTimeZone extends Value { ...@@ -70,7 +70,7 @@ public class ValueTimestampTimeZone extends Value {
private ValueTimestampTimeZone(long dateValue, long timeNanos, private ValueTimestampTimeZone(long dateValue, long timeNanos,
short timeZoneOffsetMins) { short timeZoneOffsetMins) {
if (timeNanos < 0 || timeNanos >= 24L * 60 * 60 * 1000 * 1000 * 1000) { if (timeNanos < 0 || timeNanos >= DateTimeUtils.NANOS_PER_DAY) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"timeNanos out of range " + timeNanos); "timeNanos out of range " + timeNanos);
} }
...@@ -218,7 +218,7 @@ public class ValueTimestampTimeZone extends Value { ...@@ -218,7 +218,7 @@ public class ValueTimestampTimeZone extends Value {
long dv = dateValue; long dv = dateValue;
if (n2 >= DateTimeUtils.NANOS_PER_DAY) { if (n2 >= DateTimeUtils.NANOS_PER_DAY) {
n2 -= DateTimeUtils.NANOS_PER_DAY; n2 -= DateTimeUtils.NANOS_PER_DAY;
dv = DateTimeUtils.dateValueFromAbsoluteDay(DateTimeUtils.absoluteDayFromDateValue(dateValue) + 1); dv = DateTimeUtils.incrementDateValue(dv);
} }
return fromDateValueAndNanos(dv, n2, timeZoneOffsetMins); return fromDateValueAndNanos(dv, n2, timeZoneOffsetMins);
} }
...@@ -228,25 +228,25 @@ public class ValueTimestampTimeZone extends Value { ...@@ -228,25 +228,25 @@ public class ValueTimestampTimeZone extends Value {
ValueTimestampTimeZone t = (ValueTimestampTimeZone) o; ValueTimestampTimeZone t = (ValueTimestampTimeZone) o;
// Maximum time zone offset is +/-18 hours so difference in days between local // Maximum time zone offset is +/-18 hours so difference in days between local
// and UTC cannot be more than one day // and UTC cannot be more than one day
long daysA = DateTimeUtils.absoluteDayFromDateValue(dateValue); long dateValueA = dateValue;
long timeA = timeNanos - timeZoneOffsetMins * 60_000_000_000L; long timeA = timeNanos - timeZoneOffsetMins * 60_000_000_000L;
if (timeA < 0) { if (timeA < 0) {
timeA += DateTimeUtils.NANOS_PER_DAY; timeA += DateTimeUtils.NANOS_PER_DAY;
daysA--; dateValueA = DateTimeUtils.decrementDateValue(dateValueA);
} else if (timeA >= DateTimeUtils.NANOS_PER_DAY) { } else if (timeA >= DateTimeUtils.NANOS_PER_DAY) {
timeA -= DateTimeUtils.NANOS_PER_DAY; timeA -= DateTimeUtils.NANOS_PER_DAY;
daysA++; dateValueA = DateTimeUtils.incrementDateValue(dateValueA);
} }
long daysB = DateTimeUtils.absoluteDayFromDateValue(t.dateValue); long dateValueB = t.dateValue;
long timeB = t.timeNanos - t.timeZoneOffsetMins * 60_000_000_000L; long timeB = t.timeNanos - t.timeZoneOffsetMins * 60_000_000_000L;
if (timeB < 0) { if (timeB < 0) {
timeB += DateTimeUtils.NANOS_PER_DAY; timeB += DateTimeUtils.NANOS_PER_DAY;
daysB--; dateValueB = DateTimeUtils.decrementDateValue(dateValueB);
} else if (timeB >= DateTimeUtils.NANOS_PER_DAY) { } else if (timeB >= DateTimeUtils.NANOS_PER_DAY) {
timeB -= DateTimeUtils.NANOS_PER_DAY; timeB -= DateTimeUtils.NANOS_PER_DAY;
daysB++; dateValueB = DateTimeUtils.incrementDateValue(dateValueB);
} }
int cmp = Long.compare(daysA, daysB); int cmp = Long.compare(dateValueA, dateValueB);
if (cmp != 0) { if (cmp != 0) {
return cmp; return cmp;
} }
......
...@@ -377,6 +377,9 @@ public class TestDate extends TestBase { ...@@ -377,6 +377,9 @@ public class TestDate extends TestBase {
assertEquals(y, DateTimeUtils.yearFromDateValue(date)); assertEquals(y, DateTimeUtils.yearFromDateValue(date));
assertEquals(m, DateTimeUtils.monthFromDateValue(date)); assertEquals(m, DateTimeUtils.monthFromDateValue(date));
assertEquals(d, DateTimeUtils.dayFromDateValue(date)); assertEquals(d, DateTimeUtils.dayFromDateValue(date));
long nextDateValue = DateTimeUtils.dateValueFromAbsoluteDay(next);
assertEquals(nextDateValue, DateTimeUtils.incrementDateValue(date));
assertEquals(date, DateTimeUtils.decrementDateValue(nextDateValue));
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论