99import com .swyp .picke .domain .ad .repository .AdImpressionDailyRepository ;
1010import java .time .LocalDate ;
1111import java .time .LocalDateTime ;
12+ import java .time .ZoneId ;
1213import java .util .ArrayList ;
1314import java .util .Iterator ;
1415import java .util .List ;
2526@ RequiredArgsConstructor
2627public class AdQueryService {
2728
29+ /** 노출 집계 버킷과 게재 기간은 KST 기준이다. 진입점의 기본 시간대 설정에 기대지 않는다. */
30+ private static final ZoneId KST = ZoneId .of ("Asia/Seoul" );
31+
2832 private final AdCreativeRepository adCreativeRepository ;
2933 private final AdImpressionDailyRepository adImpressionDailyRepository ;
3034
@@ -37,7 +41,7 @@ public class AdQueryService {
3741 */
3842 @ Transactional (readOnly = true )
3943 public List <AdResponse > findServableAds (AdSlotCode slot , int size ) {
40- LocalDateTime now = LocalDateTime .now ();
44+ LocalDateTime now = LocalDateTime .now (KST );
4145
4246 List <AdCreative > candidates = adCreativeRepository .findAllBySlotAndStatus (slot , AdStatus .ACTIVE ).stream ()
4347 .filter (creative -> creative .isServable (now ))
@@ -54,7 +58,7 @@ public List<AdResponse> findServableAds(AdSlotCode slot, int size) {
5458 */
5559 @ Transactional (readOnly = true )
5660 public List <AdResponse > findLandingAds () {
57- LocalDateTime now = LocalDateTime .now ();
61+ LocalDateTime now = LocalDateTime .now (KST );
5862
5963 return adCreativeRepository .findAllByStatusOrderByIdDesc (AdStatus .ACTIVE ).stream ()
6064 .filter (creative -> creative .isServable (now ))
@@ -68,7 +72,7 @@ public List<AdResponse> findLandingAds() {
6872 */
6973 @ Transactional
7074 public void recordImpressions (List <String > codes ) {
71- LocalDate today = LocalDate .now ();
75+ LocalDate today = LocalDate .now (KST );
7276
7377 List <ImpressionTarget > targets = adCreativeRepository .findAllByCodeIn (codes ).stream ()
7478 .map (creative -> new ImpressionTarget (creative .getId (), creative .getSlot ()))
0 commit comments