SQL로 날짜 변환하기
SELECT @@SYSTEM_TIME_ZONE;
# UTC -> Asia/Seoul
SELECT CONVERT_TZ('2022-04-13 00:00:00', 'UTC', 'Asia/Seoul'); # '2022-04-13 09:00:00'
SELECT CONVERT_TZ(CONCAT('2022-04-13', ' ', '00:00:00'), 'UTC', 'Asia/Seoul'); # '2022-04-13 09:00:00'
# Asia/Seoul -> UTC
SELECT CONVERT_TZ('2022-04-13 09:00:00', 'Asia/Seoul', 'UTC'); # '2022-04-13 00:00:00'
SELECT CONVERT_TZ(CONCAT('2022-04-13', ' ', '09:00:00'), 'Asia/Seoul', 'UTC'); # '2022-04-13 00:00:00'
SELECT DATE_FORMAT('2022-04-14 00:00:00', '%Y-%m-%d %H:%i:%s');
SELECT CONVERT_TZ(NOW(), @@SYSTEM_TIME_ZONE, 'Asia/Seoul');
LocalDateTime vs ZonedDateTime
- LocalDateTime vs ZonedDateTime
- LocalDateTime: 타임존 없는 DateTime
- ZonedDateTime: 타임존 있는 DateTime. LocalDateTime + ZoneId(타임존)
아래 예제를 실습한 PC의 시간은 2022-04-18T09:00:00+09:00[Asia/Seoul]이다.
- LocalDateTime 초기화: 설정한 타임존의 yyyy-MM-ddTHH:mm:ss 값이 들어감
// 애플리케이션의 타임존이 Asia/Seoul
// 현재 시간은 2022-04-18T09:00:00[Asia/Seoul]
// 타임존이 없으면, ZoneId.systemDefault()인 Asia/Seoul 값
LocalDateTime ldt = LocalDateTime.now();
// 2022-04-18T09:00:00
// 타임존을 설정하면, 타임존으로 설정됨
LocalDateTime ldtAtUtc = LocalDateTime.now(ZoneId.of("UTC"));
// 2022-04-18T00:00:00
- LocalDateTime ➡︎ ZonedDateTime: 이 시간은 타임존이 여기야!
- LocalDateTime의 yyyy-MM-ddTHH:mm:ss 값은 그대로 + 타임존만 붙음
// 애플리케이션의 타임존이 Asia/Seoul
// 현재 시간은 2022-04-18T09:00:00[Asia/Seoul]
// 2022-04-18T09:00:00 + 타임존
LocalDateTime ldt = LocalDateTime.now(); // 2022-04-18T09:00:00
ldt.atZone(ZoneId.of("Asia/Seoul")); // 2022-04-18T09:00:00+09:00[Asia/Seoul]
ldt.atZone(ZoneId.of("UTC")); // 2022-04-18T09:00:00Z[UTC]
// 2022-04-18T00:00:00 + 타임존
LocalDateTime ldtAtUtc = LocalDateTime.now(ZoneId.of("UTC")); // 2022-04-18T00:00:00
ldtAtUtc.atZone(ZoneId.of("Asia/Seoul")); // 2022-04-18T00:00:00+09:00[Asia/Seoul]
ldtAtUtc.atZone(ZoneId.of("UTC")); // 2022-04-18T00:00:00Z[UTC]
- ZonedDateTime 초기화: 설정한 타임존의 yyyy-MM-ddTHH:mm:ss 값 + 타임존
ZonedDateTime zdt = ZonedDateTime.now(); // 2022-04-18T09:00:00+09:00[Asia/Seoul]
ZonedDateTime zdtAtUtc = ZonedDateTime.now(ZoneId.of("UTC")); // 2022-04-18T00:00:00Z[UTC]
- ZonedDateTime ➡︎ LocalDateTime: 타임존만 쏙 빠짐
ZonedDateTime zdt = ZonedDateTime.now(); // 2022-04-18T09:00:00+09:00[Asia/Seoul]
zdt.toLocalDateTime(); // 2022-04-18T09:00:00
ZonedDateTime zdtAtUtc = ZonedDateTime.now(ZoneId.of("UTC")); // 2022-04-18T00:00:00Z[UTC]
zdtAtUtc.toLocalDateTime(); // 2022-04-18T00:00:00
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
System.out.println(zonedDateTime.getZone()); // System Default
zonedDateTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(zonedDateTime);
System.out.println(zonedDateTime.getZone()); // America/New_York
LocalDateTime, ZonedDateTime을 MyBatis의 SQL로 보내기
<select id="selectLocaldatetime" parameterType="map" resultType="string">
SELECT #{localDateTime};
</select>
<select id="selectZoneddatetime" parameterType="map" resultType="string">
SELECT #{zonedDateTime};
</select>
- 코드 실행 시, ZonedDateTime은 타임존이 시스템 기본 타임존으로 변경된다.
- ZoneDateTime::withZoneSameTime(ZoneId.systemDefault())의 yyyy-MM-ddTHH:mm:ss 으로 변경
readMapper.selectLocaldatetime(LocalDateTime.now());
# SELECT '2022-04-18T09:00:00'; -> Asia/Seoul
readMapper.selectLocaldatetime(LocalDate.now().atStartOfDay());
# SELECT '2022-04-18T00:00:00'; -> Asia/Seoul
readMapper.selectZoneddatetime(ZonedDateTime.now());
# SELECT '2022-04-18T09:00:00'; -> Asia/Seoul
readMapper.selectZoneddatetime(ZonedDateTime.now(ZoneId.of("UTC")));
# SELECT '2022-04-18T09:00:00'; -> Asia/Seoul
readMapper.selectZoneddatetime(ZonedDateTime.now(ZoneId.of("America/New_York")));
# SELECT '2022-04-18T09:00:00'; -> Asia/Seoul
출처