티스토리 뷰

DB

[PostgreSQL] 그날의 끝 시간(23:59:59)

개발하고싶은개발자 2023. 11. 24. 20:17

개발을 하면서 그날의 끝 시간 관련해서 제대로 동작하지 않는 문제가 있었다.

 

Member 테이블이 아래와 같이 있고, 특정 날짜 이전에 생성된 Member 리스트를 구하고 싶다는 요구사항이 왔다고 가정해 보자. (DB는 당연하게도 PostgreSQL이다)

id name created_at
1 홍길동 2023-11-24 00:00:00.000000
2 김길동 2023-11-23 23:59:59.000000
3 이길동 2023-11-23 00:00:00.000000

 

 

특정 날짜 이전에 생성된 Member 리스트를 구하기 위한 코드는 아래와 같이 작성했다.

//MemberRepository.java
public interface MemberRepository extends JpaRepository<Member, Long> {

	List<Member> findByCreatedAtLessThanEqual(LocalDateTime dateTime);
}

//TempService.java
public class TempService {
	private final MemberRepository memberRepository;

	public List<Member> getMember(LocalDate lastDate) {

		LocalDateTime calculatedDateTime = LocalDateTime.of(lastDate.getYear(), lastDate.getMonth(),
			lastDate.getDayOfMonth(), 0, 0, 0).minusNanos(1); //현재날짜 보다 이전에 생성된 데이터들을 구하기 위해 minusNanos(1)을 해줬다.

		return memberRepository.findByCreatedAtLessThanEqual(calculatedDateTime);
	}
}

맞다. LessTahnEqual이 아니라 Before을 해주면 되지만 문제상황을 알기 위해서 일단 LessTahnEqual을 사용했다고 가정해 보겠다.

 

 

위의 코드의 TeamService::getMember(LocalDate.of(2023, 11, 24))를 호출하면 결과 값이 pk id = 2, 3번인 Member 2개가 리턴될 거라고 예상할 수 있지만 실제 리턴값은 1, 2, 3번의 Member 모두가 리턴된다.

 

 

이유를 찾을 수 없어서 열심히 알아보던 중 강남언니의 블로그에서 비슷한 증상을 겪은 글을 보게 됐다.(https://blog.gangnamunni.com/post/mysql-endtime-timestamp/)

 

 

위의 글을 보고 PostgreSQL의 timestamp 타입과 관련이 있을 수도 있다고 생각했고 관련된 정보를 찾았다!

 

 

PostgreSQL의 공식문서에서 timestamp 타입에 대한 설명이 나오는데 microsecond까지만 지원이 된다고 나와있다. 하지만 우리의 코드에서는 그보다 더 정교한 타입인 nanosecond를 -1 해서 원하는 대로 동작이 되지 않았던 것이다.

 

 

따라서 아래와 같이 minusNanos(1)이 아닌 minusNanos(1000)을 했더니 원하던 대로 정상 동작하는 것을 볼 수 있었다.

//MemberRepository.java

public interface MemberRepository extends JpaRepository<Member, Long> {

	List<Member> findByCreatedAtLessThanEqual(LocalDateTime dateTime);
}

//TempService.java
public class TempService {
	private final MemberRepository memberRepository;

	public List<Member> getMember(LocalDate lastDate) {

		LocalDateTime calculatedDateTime = LocalDateTime.of(lastDate.getYear(), lastDate.getMonth(),
			lastDate.getDayOfMonth(), 0, 0, 0).minusNanos(1000); //현재날짜 보다 이전에 생성된 데이터들을 구하기 위해 minusNanos(1)을 해줬다.

		return memberRepository.findByCreatedAtLessThanEqual(calculatedDateTime);
	}
}

DB의 타입에 대해서 무신경하게 개발하고 있었던 것 같아서 반성하는 계기가 됐다.

 


ref

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30