๋ฐ์ํ
LocalDateTime.MIN to Date, LocalDateTime.MAX to Date -> java.lang.IllegalArgumentException: java.lang.ArithmeticException: long overflow
- java.util.Date ํด๋์ค๋ฅผ ์ฌ์ฉํ์ง ์์์ผ ํ๋ ์ด์ ๊ฐ ์๋ ์์ด ๋ง๋ค๋ ์ ์ ์์ง๋ง, ์ด์ฉ ์ ์์ด Date ํด๋์ค๋ฅผ ์ด์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์๋ค. (๋์ ๊ฒฝ์ฐ๋ ํ์ฌ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ผ์๋ฅผ ๋ค๋ฃฐ ๋ Date๋ฅผ ์ฌ์ฉ์ค์ด๊ณ (ใ ใ ), ๊ทธ ์ธ์๋ ์ด์ ๊ฐ ์์๋ค)
- ์๋ฌดํผ, ๊ทธ๋์ LocalDateTime์ Date๋ก ๋ณํํ๋ค๋ณด๋ ์ค๋ฅ๊ฐ ๋ฐ์ํด ์ด๋ฅผ ๊ณต์ ํ๊ณ ์ ํ๋ค.
๐ LocalDate(LocalDateTime) to Date
// Timestamp์ valueOf ๋ฉ์๋ ์ฌ์ฉ
// Timestamp๊ฐ Date์ ์์ ๋ฐ์
public Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) {
return java.sql.Timestamp.valueOf(dateToConvert);
}
// Date.from ๋ฉ์๋ ์ฌ์ฉ
// LocalDate๋ฅผ Instant ๊ฐ์ฒด๋ก ๋ง๋ค๊ณ Date.from(Instant instant) ์ด์ฉํด์ ๋ณํ
Date convertToDateViaInstant(LocalDateTime dateToConvert) {
return java.util.Date
.from(dateToConvert.atZone(ZoneId.systemDefault())
.toInstant());
}
- LocalDate(LocalDateTime)์ Date๋ก ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ ์ค ํฌ๊ฒ ๋๊ฐ์ง๋ฅผ ์๊ฐํ์๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- Timestamp์ valueOf ๋ฉ์๋๋ฅผ ์ฌ์ฉํด Timestamp ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ์ด๋ Timestamp๋ Date๋ฅผ ์์๋ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ Date๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
- Instant ๊ฐ์ฒด๋ก ๋ณํ ํ Date.from ๋ฉ์๋๋ฅผ ์ฌ์ฉํด Date ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- ์ด๋ 2๋ฒ์งธ ๋ฐฉ๋ฒ์ผ๋ก ์ ํ ์ java.lang.IllegalArgumentException: java.lang.ArithmeticException: long overflow ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
- ์ ํํ ๋งํ๋ฉด 1๋ฒ์งธ ๋ฐฉ๋ฒ๋ ์ ์์ ์ผ๋ก ๊ฐ์ด ๋ณํ๋๋๊ฑด ์๋๋ค. (์ค๋ฅ๋ง ์๋ ๋ฟ์ด์ง overflow๊ฐ ๋ฐ์ํด ๊ฐ์ด ์ด์ํ๊ฒ ์ ์ฅ๋๋ค.)
๐ง LocalDateTime.MAX -> Instant -> Date ์๋ฌ ๋ฐ์ ์ด์ (MIN๋ ๋์ผํ ์๋ฌ)
@Test
public void convertToDateViaInstant_MAX() {
LocalDateTime MAX_LOCAL_DATE_TIME = LocalDateTime.MAX;
System.out.println("MAX_LOCAL_DATE_TIME = " + MAX_LOCAL_DATE_TIME); // 1
Instant instant = MAX_LOCAL_DATE_TIME.atZone(ZoneId.systemDefault()).toInstant();
System.out.println("instant = " + instant); // 2
Date date = Date.from(instant);
System.out.println("date = " + date); // 3
}
// 1
MAX_LOCAL_DATE_TIME = +999999999-12-31T23:59:59.999999999
// 2
instant = +999999999-12-31T14:59:59.999999999Z
// 3
java.lang.IllegalArgumentException: java.lang.ArithmeticException: long overflow
- ์์ ์ฝ๋๋ฅผ ๋ณด์์ ๋, ์ผ๋จ LocalDateTime.MAX -> Instant ๊ฐ์ฒด๋ก์ ๋ณํ์ ์ฑ๊ณต์ ์ผ๋ก ๋ณด์ธ๋ค.
- Instant -> Date๋ก ๋ณํ ํ์ ๋ long overflow๊ฐ ๋ฐ์ํ๋ค.
- ์ด๋, Date๊ฐ Instant๋ณด๋ค ๋ ์ข์ ๋ฒ์์ ์ผ์๋ฅผ ์ ์ฅํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. Date.from docs์ ๋ณด๋ฉด Exception์ด ๋ฐ์ํ ๊ฑฐ๋ผ๊ณ ์ค๋ช ๋ ๋์ด์๋ค.
๐โ๏ธ LocalDateTime์ MIN๊ณผ MAX ๊ฐ
/**
* The minimum supported {@code LocalDateTime}, '-999999999-01-01T00:00:00'.
* This is the local date-time of midnight at the start of the minimum date.
* This combines {@link LocalDate#MIN} and {@link LocalTime#MIN}.
* This could be used by an application as a "far past" date-time.
*/
public static final LocalDateTime MIN = LocalDateTime.of(LocalDate.MIN, LocalTime.MIN);
/**
* The maximum supported {@code LocalDateTime}, '+999999999-12-31T23:59:59.999999999'.
* This is the local date-time just before midnight at the end of the maximum date.
* This combines {@link LocalDate#MAX} and {@link LocalTime#MAX}.
* This could be used by an application as a "far future" date-time.
*/
public static final LocalDateTime MAX = LocalDateTime.of(LocalDate.MAX, LocalTime.MAX);
- MIN = -99999999๋ 01์ 01์ผ 00:00:00
- MAX = 99999999๋ 12์ 31์ผ 23:59:59.999999999
๐โ๏ธ Instant์ MIN๊ณผ MAX ๊ฐ
/**
* The minimum supported {@code Instant}, '-1000000000-01-01T00:00Z'.
* This could be used by an application as a "far past" instant.
* <p>
* This is one year earlier than the minimum {@code LocalDateTime}.
* This provides sufficient values to handle the range of {@code ZoneOffset}
* which affect the instant in addition to the local date-time.
* The value is also chosen such that the value of the year fits in
* an {@code int}.
*/
public static final Instant MIN = Instant.ofEpochSecond(MIN_SECOND, 0);
/**
* The maximum supported {@code Instant}, '1000000000-12-31T23:59:59.999999999Z'.
* This could be used by an application as a "far future" instant.
* <p>
* This is one year later than the maximum {@code LocalDateTime}.
* This provides sufficient values to handle the range of {@code ZoneOffset}
* which affect the instant in addition to the local date-time.
* The value is also chosen such that the value of the year fits in
* an {@code int}.
*/
public static final Instant MAX = Instant.ofEpochSecond(MAX_SECOND, 999_999_999);
- MIN = -1000000000๋ 01์ 01์ผ T00:00Z
- MAX = 1000000000๋ 12์ 31์ผ T23:59:59.999999999Z
๊ฒฐ๋ก
- Date ํด๋์ค๋ฅผ ์ฌ์ฉํ์ง ๋ง์~; ^^
- ๋ง์ฝ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด, LocalDate ๋ฑ ๋ค๋ฅธ ํด๋์ค๋ค๊ณผ ์ผ์ ์ ์ฅ ๋ฒ์๊ฐ ๋ค๋ฅด๋ค๋ ์ ์ ์๊ฐํ๊ณ ์ฌ์ฉํ์!
๐ Reference
๋ฐ์ํ