package com.snp.batch.service; import com.snp.batch.global.repository.BatchLastExecutionRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; @Slf4j @Service public class BatchDateService { private final BatchLastExecutionRepository repository; public BatchDateService(BatchLastExecutionRepository repository) { this.repository = repository; } public Map getDateRangeWithoutTimeParams(String apiKey) { return repository.findDateRangeByApiKey(apiKey) .map(projection -> { Map params = new HashMap<>(); LocalDateTime fromTarget = (projection.getRangeFromDate() != null) ? projection.getRangeFromDate() : projection.getLastSuccessDate(); LocalDateTime toTarget = (projection.getRangeToDate() != null) ? projection.getRangeToDate() : LocalDateTime.now(); // 2. 파라미터 맵에 날짜 정보 매핑 putDateParams(params, "from", fromTarget); putDateParams(params, "to", toTarget); // 3. 고정 값 설정 params.put("shipsCategory", "0"); return params; }) .orElseGet(() -> { log.warn("해당 apiKey에 대한 데이터를 찾을 수 없습니다: {}", apiKey); return new HashMap<>(); }); } /** * LocalDateTime에서 연, 월, 일을 추출하여 Map에 담는 헬퍼 메소드 */ private void putDateParams(Map params, String prefix, LocalDateTime dateTime) { if (dateTime != null) { params.put(prefix + "Year", String.valueOf(dateTime.getYear())); params.put(prefix + "Month", String.valueOf(dateTime.getMonthValue())); params.put(prefix + "Day", String.valueOf(dateTime.getDayOfMonth())); } } public Map getDateRangeWithTimezoneParams(String apiKey) { return repository.findDateRangeByApiKey(apiKey) .map(projection -> { Map params = new HashMap<>(); // 'Z'를 문자열 리터럴이 아닌 실제 타임존 기호(X)로 처리 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSX"); // 한국 시간을 UTC로 변환하는 헬퍼 메소드 (아래 정의) params.put("fromDate", formatToUtc(projection.getRangeFromDate() != null ? projection.getRangeFromDate() : projection.getLastSuccessDate(), formatter)); LocalDateTime toDateTime = projection.getRangeToDate() != null ? projection.getRangeToDate() : LocalDateTime.now(); params.put("toDate", formatToUtc(toDateTime, formatter)); return params; }) .orElseGet(() -> { log.warn("해당 apiKey에 대한 데이터를 찾을 수 없습니다: {}", apiKey); return new HashMap<>(); }); } public Map getDateRangeWithTimezoneParams(String apiKey, String dateParam1, String dateParam2) { return repository.findDateRangeByApiKey(apiKey) .map(projection -> { Map params = new HashMap<>(); // 'Z'를 문자열 리터럴이 아닌 실제 타임존 기호(X)로 처리 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSX"); // 한국 시간을 UTC로 변환하는 헬퍼 메소드 (아래 정의) params.put(dateParam1, formatToUtc(projection.getRangeFromDate() != null ? projection.getRangeFromDate() : projection.getLastSuccessDate(), formatter)); LocalDateTime toDateTime = projection.getRangeToDate() != null ? projection.getRangeToDate() : LocalDateTime.now(); params.put(dateParam2, formatToUtc(toDateTime, formatter)); return params; }) .orElseGet(() -> { log.warn("해당 apiKey에 대한 데이터를 찾을 수 없습니다: {}", apiKey); return new HashMap<>(); }); } // 한국 시간(LocalDateTime)을 UTC 문자열로 변환하는 로직 private String formatToUtc(LocalDateTime localDateTime, DateTimeFormatter formatter) { if (localDateTime == null) return null; // 1. 한국 시간대(KST)임을 명시 // 2. UTC로 시간대를 변경 (9시간 빠짐) // 3. 포맷팅 (끝에 Z가 자동으로 붙음) return localDateTime.atZone(ZoneId.of("Asia/Seoul")) .withZoneSameInstant(ZoneOffset.UTC) .format(formatter); } }