Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;

@Service
Expand All @@ -33,16 +34,17 @@ public DashboardResponse getDashboardData(Long memberId) {
}

// 3. 기본 데이터 계산
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul")); // 한국 시간대 기준 오늘 날짜
int budgetAmount = period.getBudgetAmount();
long totalExpense = expenseRepository.sumAmountByBudgetPeriod(period);
long remainingBudget = Math.max(0, budgetAmount - totalExpense);
double usageRate = (budgetAmount > 0) ? (double) totalExpense / budgetAmount * 100 : 0;
double savingRate = Math.max(0, 100 - usageRate);

long totalDays = ChronoUnit.DAYS.between(period.getStartDate(), period.getEndDate()) + 1;
long elapsedDays = Math.min(ChronoUnit.DAYS.between(period.getStartDate(), LocalDate.now()) + 1,
long elapsedDays = Math.min(ChronoUnit.DAYS.between(period.getStartDate(), today) + 1,
totalDays);
long remainingDays = Math.max(0, ChronoUnit.DAYS.between(LocalDate.now(), period.getEndDate()));
long remainingDays = Math.max(0, ChronoUnit.DAYS.between(today, period.getEndDate()));
double progressRate = ((double) elapsedDays / totalDays) * 100;
long dailyRecommended = (remainingDays > 0) ? remainingBudget / remainingDays : 0;

Expand All @@ -58,7 +60,7 @@ public DashboardResponse getDashboardData(Long memberId) {
// 4. 마감일 도달 체크 및 처리
boolean showPeriodComplete = false;
DashboardResponse.PeriodCompleteDetail periodCompleteDetail = null;
if (LocalDate.now().isAfter(period.getEndDate())) {
if (today.isAfter(period.getEndDate())) {
// 예산 초과 여부에 따라 completionType 결정
CompletionType completionType = totalExpense <= budgetAmount
? CompletionType.SUCCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.List;
import java.util.Locale;
Expand All @@ -39,8 +40,9 @@ public ExpenseCreateResponse createExpense(Long memberId, ExpenseCreateRequest r
.orElseThrow(() -> new BusinessException(ErrorCode.ACTIVE_PERIOD_NOT_FOUND));

// 2. 날짜 설정 및 오늘 첫 기록 여부 확인
LocalDate spentDate = (request.getSpentDate() != null) ? request.getSpentDate() : LocalDate.now();
boolean isTodayRecord = spentDate.equals(LocalDate.now());
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul")); // 한국 시간대 기준 오늘 날짜
LocalDate spentDate = (request.getSpentDate() != null) ? request.getSpentDate() : today;
boolean isTodayRecord = spentDate.equals(today);
boolean todayFirstExpense = !expenseRepository.existsByBudgetPeriodAndSpentDate(budgetPeriod,
spentDate);

Expand All @@ -64,7 +66,7 @@ public ExpenseCreateResponse createExpense(Long memberId, ExpenseCreateRequest r
long remainingBudget = Math.max(0, budgetAmount - totalExpense);
double usageRate = (double) totalExpense / budgetAmount * 100;
long remainingDays = Math.max(1,
java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), budgetPeriod.getEndDate()));
java.time.temporal.ChronoUnit.DAYS.between(today, budgetPeriod.getEndDate()));
long dailyRecommended = remainingBudget / remainingDays;

// 6. 예산 초과 감지 시 자동 종료
Expand Down Expand Up @@ -228,8 +230,9 @@ public ExpenseUpdateResponse updateExpense(Long memberId, Long expenseId, Expens
int budgetAmount = budgetPeriod.getBudgetAmount();
long remainingBudget = Math.max(0, budgetAmount - totalExpense);
double usageRate = (double) totalExpense / budgetAmount * 100;
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul"));
long remainingDays = Math.max(1,
java.time.temporal.ChronoUnit.DAYS.between(LocalDate.now(), budgetPeriod.getEndDate()));
java.time.temporal.ChronoUnit.DAYS.between(today, budgetPeriod.getEndDate()));
long dailyRecommended = remainingBudget / remainingDays;

// 예산 초과 감지
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -43,7 +44,7 @@ public StampResponse getStamps(Long memberId, Long periodId) {
// 이전/다음 기간 탐색 정보 조회
StampResponse.NavigationDto navigation = buildNavigation(memberId, period);

LocalDate today = LocalDate.now();
LocalDate today = LocalDate.now(ZoneId.of("Asia/Seoul")); // 한국 시간대 기준 오늘 날짜
List<StampResponse.StampDetail> stampDetails = new ArrayList<>();
int stampedDaysCount = 0;

Expand Down
15 changes: 12 additions & 3 deletions src/main/java/com/leets/monifit_be/global/config/JpaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Optional;
Expand All @@ -13,12 +14,20 @@
@EnableJpaAuditing(dateTimeProviderRef = "auditingDateTimeProvider")
public class JpaConfig {

private static final ZoneId KOREA_ZONE = ZoneId.of("Asia/Seoul");

/**
* JPA Auditing에서 사용할 시간대를 한국(Asia/Seoul)으로 설정
* @CreatedDate, @LastModifiedDate가 한국 시간으로 저장됨
* JPA Auditing에서 사용할 시간을 한국 시간대(Asia/Seoul) 기준으로 생성
*
* Instant.now()를 사용하여 현재 순간(UTC)을 가져온 후
* Asia/Seoul 시간대로 변환하여 LocalDateTime 반환
*
* 이 방식은 서버 시스템 시간대나 JDBC serverTimezone 설정과 무관하게
* 항상 정확한 한국 시간을 생성합니다.
*/
@Bean
public DateTimeProvider auditingDateTimeProvider() {
return () -> Optional.of(LocalDateTime.now(ZoneId.of("Asia/Seoul")));
return () -> Optional.of(
LocalDateTime.ofInstant(Instant.now(), KOREA_ZONE));
}
}