시간 설정 방법

박영준·2023년 8월 23일
0

Spring

목록 보기
55/58

1. 필요성

일반적으로 프로젝트 내에 시간은 UTC(세계표준시간)으로 설정돼있다.

그러나 프로젝트를 목적에 따라 만들다보면, 한국(서울)의 시간(KST, Korea Standard Time)으로 설정해야할 때가 있다.
KST 는 UTC+9 시간을 더한 시간이다.

2. 방법

방법 1. Timezone 설정

@SpringBootApplication
public class PracticeApplication {

    public static void main(String[] args) {
        SpringApplication.run(PracticeApplication.class, args);

        LocalDateTime now = LocalDateTime.now();
        System.out.println("현재시간 " + now);
    }

	// Timezone 설정
    @PostConstruct
    public void init() {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));		// 한국은 "Asia/Seoul"
    }
}

@PostConstruct :빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출된다.

단, 이 방법은 SpringBootApplication (즉, 해당 프로젝트 전체) 에 전역적으로 시간을 설정하는 방법이다.
예를 들어, post 는 UTC 로 반환하나 chatting 은 KST 로 하고 싶은 경우엔 적합한 방법이 아닐 수 있다는 것이다.

방법 2. 개별적으로 설정

채팅방 목록을 조회할 때 카카오톡 채팅방과 동일하게,
최신 보낸 메시지, 최신 메시지가 보내진 시간을 반환하기 위한 코드다.

MessageRoomService

@Service
@RequiredArgsConstructor
public class MessageRoomService {

	...
    
    // 쪽지방 전체 조회
    public List<MessageResponseDto> findAllRoomByUser(User user) {
        List<MessageRoom> messageRooms = messageRoomRepository.findByUserOrReceiver(user, user.getNickname());

        List<MessageResponseDto> messageRoomDtos = new ArrayList<>();

        for (MessageRoom messageRoom : messageRooms) {
            //  user 가 sender 인 경우
            if (user.getNickname().equals(messageRoom.getSender())) {
                MessageResponseDto messageRoomDto = new MessageResponseDto(
                        messageRoom.getId(),
                        messageRoom.getReceiver(),        // roomName
                        messageRoom.getRoomId(),
                        messageRoom.getSender(),
                        messageRoom.getReceiver(),
                        messageRoom.getCreatedAt());

                // 가장 최신 메시지 & 생성 시간 조회
                Message latestMessage = messageRepository.findTopByRoomIdOrderByCreatedAtDesc(messageRoom.getRoomId());
                if (latestMessage != null) {
                    messageRoomDto.setLatestMessageCreatedAt(latestMessage.getCreatedAt());
                    messageRoomDto.setLatestMessageContent(latestMessage.getMessage());
                }

                messageRoomDtos.add(messageRoomDto);
            // user 가 receiver 인 경우
            } else {
                MessageResponseDto messageRoomDto = new MessageResponseDto(
                        messageRoom.getId(),
                        messageRoom.getSender(),        // roomName
                        messageRoom.getRoomId(),
                        messageRoom.getSender(),
                        messageRoom.getReceiver(),
                        messageRoom.getCreatedAt());

                // 가장 최신 메시지 & 생성 시간 조회
                Message latestMessage = messageRepository.findTopByRoomIdOrderByCreatedAtDesc(messageRoom.getRoomId());
                if (latestMessage != null) {
                    messageRoomDto.setLatestMessageCreatedAt(latestMessage.getCreatedAt());
                    messageRoomDto.setLatestMessageContent(latestMessage.getMessage());
                }

                messageRoomDtos.add(messageRoomDto);
            }
        }

        return messageRoomDtos;
    }

}

MessageResponseDto

@Getter
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MessageResponseDto {
    private Long id;
    private String roomName;
    private String sender;
    private String roomId;
    private String receiver;
    private Long postId;
    private String message;
    private LocalDateTime createdAt;

	...

    // 사용자 관련 쪽지방 전체 조회
    public MessageResponseDto(Long id, String roomName, String roomId, String sender, String receiver, LocalDateTime createdAt) {
        this.id = id;
        this.roomName = roomName;
        this.roomId = roomId;
        this.sender = sender;
        this.receiver = receiver;
        
        ZoneId utcZone = ZoneId.of("UTC");
        ZoneId koreaZone = ZoneId.of("Asia/Seoul");
        ZonedDateTime utcTime = createdAt.atZone(utcZone);
        ZonedDateTime koreaTime = utcTime.withZoneSameInstant(koreaZone);

        this.createdAt = koreaTime.toLocalDateTime();
    }


    public MessageResponseDto(String roomId) {
        this.roomId = roomId;
    }

    public void setLatestMessageContent(String message) {
        this.message = message;
    }

	// KST 시간 설정
    public void setLatestMessageCreatedAt(LocalDateTime createdAt) {
    
    	// 1. 객체 각각 생성
        ZoneId utcZone = ZoneId.of("UTC");				// UTC 를 사용하여 이(UTC)를 나타내는 ZoneId 객체를 생성
        ZoneId koreaZone = ZoneId.of("Asia/Seoul");		// Asia/Seoul 를 사용하여 한국 표준시(KST)를 나타내는 ZoneId 객체를 생성
        
        // 2. createdAt 객체 → ZonedDateTime 객체로 변환
        ZonedDateTime utcTime = createdAt.atZone(utcZone);					// createdAt 객체를 UTC 시간대에 해당하는 ZonedDateTime 객체로 변환
        ZonedDateTime koreaTime = utcTime.withZoneSameInstant(koreaZone);	// utcTime 을 사용하여 한국 시간대에 해당하는 ZonedDateTime 객체를 생성

		// 3. koreaTime 에서 한국 시간대의 시간 정보를 유지한 채로 LocalDateTime 객체로 변환하여 createdAt 필드를 설정
        this.createdAt = koreaTime.toLocalDateTime();
    }
}

참고: Spring boot Timezone 설정하기

profile
개발자로 거듭나기!

0개의 댓글