티스토리 뷰

개발을 하며 얼마나 시간 관련 기능을 사용해봤는가?
도메인은 다양하고, 기능들도 다양할 겁니다.
지금까지 실무에서 경험해본 것은 "라이브 커머스", "메시지 전송" 도메인을 경험해보았습니다.
하지만 라이브 커머스에서는 Node.js인 Express.js 프레임워크를 사용하여서 아쉽지만, 메시지 전송에는 Spring을 사용하기 때문에 관련 기능 및 생각으로 작성해보려고 합니다.
메시지 전송에서 시간과 관련된 기능을 무엇일까?
메시지 즉시/예약 전송
이거 딱 한 개라고 생각합니니다.

사용할 때마다 다른 모습의 시간 형태 ㅠㅠ
시간 및 날짜의 데이터를 전달하거나 저장할 때, 같지만 다 다른 형태로 되어 있다고 생각이 듭니다.
- 클라이언트 → 서버 : 데이터를 요청 할 때
- 서버 → DB : 데이터를 저장 할 때
- 서버 → 다른 서비스 API 서버 : API 호출하여 시간 관련 기능 요청할 때
- 서버 → 클라이언트 : 데이터를 응답 할 때
1) 클라이언트 → 서버
# 1) YYYY-MM-DD
2025-09-27
# 2) YYYYMMDDHHmmss
20250913102500
2) 서버 → DB
# 1) LocalDateTime
2025-09-11T21:30:45
# 2) DB TimeStamp
2025-09-13 10:25:30
3) 서버 → 다른 서비스 API 서버
# 1) A 업체의 시간 요청 규격
2025-09-13 10:25
# 2) B 업체의 시간 요청 규격
1694570700 # 2025-09-13 10:25:00 KST 기준 UTC 초 값
4) 서버 → 클라이언트
# 1) YYYY-MM-DD HH:mm:ss
2025-09-13 10:25:00
# 2) Unix Timestamp (밀리초)
16945707000000

그래서 우리는 문자열로 들어온 시간 정보를 LocalDateTime 객체로 변환하여 사용할 것이며,
API 호출하기 위한 시간 변경하는 법(formatter)를 알아볼 겁니다.
해외에 서비스를 하지 않으니 LocalDateTime에 대해서 알아보자
LocalDateTime의 기준 시간
되게 궁금했다.
브라질에서 기동하면 그 시간으로 보일까?
우리가 보는 시각은 Local이 들어간 객체이니 한국 시간으로 보일까? 브라질 시간으로 보일까?
이것의 답은 "애플리케이션이 실행 중인 서버 OS의 시스템 시계"를 기준으로 합니다.
// method
public static LocalDateTime now() {
return now(Clock.systemDefaultZone());
}
// 1 depth
public static Clock systemDefaultZone() {
return new SystemClock(ZoneId.systemDefault());
}
// 2 depth
public static ZoneId systemDefault() {
return TimeZone.getDefault().toZoneId();
}
메서드를 뜯어보니 defaultZone, default 값을 사용하는 것을 볼 수 있습니다.
이것은 현재 JVM이 실행되는 OS 환경의 기본 시간대를 가져오는 말입니다.
그럼 브라질에서 기동하면 그 시간으로 보일까?의 질문의 실질적의 답은
"그 컴퓨터 세팅된 값에 따라 달라져~ 브라질에서도 한국시간으로 기동할 수 있어~" 라고 하고 싶네요ㅋㅋㅋㅋㅋㅋ
LocalDateTime은 타임존 정보를 가지지 않는다.
LocalDateTime은 그냥 2025-09-13 09:12:34와 같은 값만 저장하는 것입니다.
따라서 어디 기준인지의 값인지는 파악은 할 수 없게 됩니다.
뭐 기동한 사람은 알겠지.. 그 시간을 사용하는 사람은 모른다는거..

LocalDateTime 메서드 모음
static메서드 (객체 생성 관련)
/*********
* LocalDateTIme의 Static 메서드
*****/
// 1) now() 계열
LocalDateTime now = LocalDateTime.now();
// 2025-09-13T14:04:08.269771700
LocalDateTime now2 = LocalDateTime.now(ZoneId.of("America/Chicago"));
// 2025-09-13T01:02:41.282564400
LocalDateTime now3 = LocalDateTime.now(ZoneId.of("Asia/Seoul"));
// 2025-09-13T15:02:41.284580500
// 2) 최대, 최소
System.out.println("MAX : " + LocalDateTime.MAX);
// +999999999-12-31T23:59:59.999999999
System.out.println("MIN : " + LocalDateTime.MIN);
// -999999999-01-01T00:00
// 3) of() 계열
LocalDateTime t1 = LocalDateTime.of(2025, 9, 11, 21, 30);
// 2025-09-11T21:30
LocalDateTime t2 = LocalDateTime.of(2025, Month.SEPTEMBER, 11, 21, 30, 45);
// 2025-09-11T21:30:45
LocalDateTime t3 = LocalDateTime.of(2025, 9, 11, 21, 30, 45, 123_456_789);
// 2025-09-11T21:30:45.123456789
LocalDate d = LocalDate.of(2025, 9, 11);
LocalTime tm = LocalTime.of(21, 30, 45);
LocalDateTime t4 = LocalDateTime.of(d, tm);
// 2025-09-11T21:30:45
// 4) parse() 계열 문자열 → LocalDateTime
String input = "20250911213045"; // 입력 문자열
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime b1 = LocalDateTime.parse(input, f1);
// 2025-09-11T21:30:45
// 5) 원하는 시간 형태로
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm");
String str2 = b1.format(f2);
// 2025-09-13 10:25
ZoneId seoulZone = ZoneId.of("Asia/Seoul");
long epochSeconds = dt.atZone(seoulZone).toEpochSecond();
// 1694570700
일반 메서드 (시간 컨트롤 관련)
뭘 좋아 할지 몰라서 다 준비는 해보았습니다.
// 1. LocalDateTime 생성
LocalDateTime ldt = LocalDateTime.of(2025, Month.SEPTEMBER, 11, 21, 30, 45, 123_000_000);
// ▶ Original LocalDateTime: 2025-09-11T21:30:45.123
/* ------------------------------------------------------------- */
// 2. 날짜/시간 조회
System.out.println("Year : " + ldt.getYear()); // 2025
System.out.println("Month : " + ldt.getMonth()); // SEPTEMBER
System.out.println("MonthValue : " + ldt.getMonthValue()); // 9
System.out.println("DayOfMonth : " + ldt.getDayOfMonth()); // 11
System.out.println("DayOfWeek : " + ldt.getDayOfWeek()); // THURSDAY
System.out.println("DayOfYear : " + ldt.getDayOfYear()); // 254
System.out.println("Hour : " + ldt.getHour()); // 21
System.out.println("Minute : " + ldt.getMinute()); // 30
System.out.println("Second : " + ldt.getSecond()); // 45
System.out.println("Nano : " + ldt.getNano()); // 123000000
/* ------------------------------------------------------------- */
// 3. 날짜/시간 연산
System.out.println("Plus 1 year : " + ldt.plusYears(1)); // 2026-09-11T21:30:45.123
System.out.println("Minus 2 months : " + ldt.minusMonths(2)); // 2025-07-11T21:30:45.123
System.out.println("Plus 10 days : " + ldt.plusDays(10)); // 2025-09-21T21:30:45.123
System.out.println("Minus 3 hours : " + ldt.minusHours(3)); // 2025-09-11T18:30:45.123
System.out.println("Plus 15 minutes : " + ldt.plusMinutes(15)); // 2025-09-11T21:45:45.123
System.out.println("Plus 30 seconds : " + ldt.plusSeconds(30)); // 2025-09-11T21:31:15.123
/* ------------------------------------------------------------- */
// 4. 변환
LocalDate datePart = ldt.toLocalDate();
LocalTime timePart = ldt.toLocalTime();
OffsetDateTime odt = ldt.atOffset(ZoneOffset.ofHours(9));
ZonedDateTime zdt = ldt.atZone(ZoneId.of("Asia/Seoul"));
long epochSec = ldt.toEpochSecond(ZoneOffset.ofHours(9));
System.out.println("LocalDate : " + datePart); // 2025-09-11
System.out.println("LocalTime : " + timePart); // 21:30:45.123
System.out.println("OffsetDateTime : " + odt); // 2025-09-11T21:30:45.123+09:00
System.out.println("ZonedDateTime : " + zdt); // 2025-09-11T21:30:45.123+09:00[Asia/Seoul]
System.out.println("EpochSecond(KST): " + epochSec); // 1757603445
/* ------------------------------------------------------------- */
// 5. 비교
LocalDateTime ldt2 = LocalDateTime.of(2025, 9, 11, 22, 0);
System.out.println("Is before ldt2? " + ldt.isBefore(ldt2)); // true
System.out.println("Is after ldt2? " + ldt.isAfter(ldt2)); // false
System.out.println("Is equal ldt2? " + ldt.isEqual(ldt2)); // false
/* ------------------------------------------------------------- */
// 6. with 메서드 (특정 필드 변경)
LocalDateTime changed = ldt.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
System.out.println("Changed LocalDateTime: " + changed);
// Changed LocalDateTime: 2025-09-01T00:00
/* ------------------------------------------------------------- */
// 7. 포맷팅
DateTimeFormatter ff1 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
DateTimeFormatter ff2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter ff3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
System.out.println("Formatted f1: " + ldt.format(ff1)); // 20250911213045
System.out.println("Formatted f2: " + ldt.format(ff2)); // 2025-09-11 21:30:45
System.out.println("Formatted f3: " + ldt.format(ff3)); // 2025-09-11 21:30

결론
저는 실무에서는 YYYYMMDDHHmmss 형태로 값이 들어오고 있습니다.
위에서 메서드 설명했던 것과 같이 아래와 같은 행태로 사용해야 겠습니다.
// 1. 파싱 (문자열 → LocalDateTime)
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime dt = LocalDateTime.parse(input, parser);
// 2. A 업체 규격: "yyyy-MM-dd HH:mm"
DateTimeFormatter aFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String aResult = dt.format(aFormatter);
System.out.println("A 업체 요청 규격: " + aResult);
// A 업체 요청 규격: 2025-09-13 10:25
// 3. B 업체 규격: Unix Time (초 단위, UTC 기준)
ZoneId seoulZone = ZoneId.of("Asia/Seoul");
long epochSeconds = dt.atZone(seoulZone).toEpochSecond();
System.out.println("B 업체 요청 규격: " + epochSeconds);
// B 업체 요청 규격: 1694570700
또한 해외에서도 서비스를 한다면 LocalDateTime을 이용하는 것이 아닌 Instant를 이용하는 법을 알아야하는데요..
이건 제가 사이드 프로젝트하면서 자아실현을 하거나.. 나중에 해외서비스도 한다면 다뤄보도록 하겠습니다.

감사합니다.
'프로그래밍 언어 > 💫JAVA' 카테고리의 다른 글
| [JAVA] JVM 개념 원리 : 백엔드가 이걸 모른다고? (0) | 2025.03.10 |
|---|---|
| [JAVA] 객체지향 프로그래밍을 배우는 블랙잭 게임 (4/4) : 개선 사항 및 후기 (1) | 2024.06.24 |
| [JAVA] 객체지향 프로그래밍을 배우는 블랙잭 게임 (3/4) : 비즈니스 로직 개발 및 실행 (2) | 2024.06.18 |
| [JAVA] 객체지향 프로그래밍을 배우는 블랙잭 게임 (2/4) : 도메인 개발 (0) | 2024.06.12 |
| [JAVA] 객체지향 프로그래밍을 배우는 블랙잭 게임 (1/4) : 설계 단계 (0) | 2024.06.06 |
- Total
- Today
- Yesterday
- 개발
- spring
- Flutter
- 개발환경
- Fetch
- Front
- 개발자
- 트랜잭션
- Spring Security
- 코딩테스트
- 깃허브 액션
- CI/CD
- 프로세스
- 데이터 베이스
- 소셜로그인
- aws
- 디자인패턴
- 계단 오르기
- DBeaver
- 네트워크
- 그리디
- 시간 객체
- 개발블로그
- 멀티모듈
- 알고리즘
- 카카오 로그인
- JPA 페이징
- JavaScript
- BFS
- java
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 31 |