날짜와 시간

황상익·2024년 5월 16일

Inflearn JAVA

목록 보기
29/61

날짜와 시간 라이브러리가 필요한 이유
날짜와 시간을 계산 하는 것은 단순하게 생각하면 쉬워보일 수 있지만 보기보다 까다로움

1. 자바 날짜와 시간 라이브러리 여갓

JDK (1.0)

문제점
타임존 처리 부족: 초기 Date 클래스는 타임 존을 제대로 처리 X
불편한 날짜 시간 연산 : 날짜 간 연산이난, 증감등을 처리하기 어려움
불변 객체 부제 : Date 객체는 변경 가능, 데이터가 쉽게 변경 가능 -> 버그 발생

해결책
JDK 1.1에서 Calendar 클래스 도입으로 타임존 지원 개선

JDK 1.1

문제점
사용성 저하 : Calendar는 사용하기 복잡. 직관적X
성능문제 : 일부 사용 사례에서 성능이 저하
불변 객체 부제 : Calendar 객체도 변경 가능, 사이드 이펙트. 스레드 안정성 문제

해결책
Joda-time 오픈소스 라이브러리 도입으로 사용성 성능 불변성 문제 해결

Joda-time
문제점
표준 라이브러리가 아님: Joda-time은 외부 라이브러, 자바 표준에 포함X

해결책
java.time 패키지를 표준 API롤 도입

JDK8(1.8)
java.time 패키지는 이전 API 문제점을 해결, 사용성, 성능, 스레드 안정성, 타임존 처리에 크게 개선, 변경 불가능한 불변 객체 설꼐로 사이드 이펙트, 스레드 안정성 보장, 직관적 API 제공으로 날짜와 시간 연산을 단순화
LocalDate LocalTime LocalDateTime ZonedDateTime Instant등의 클래스를 포함

자바 날짜와 시간 라이브러리 소개

LocalDate: 날짜만 표현 (년, 월, 일)
LocalTime: 시간만 표현할때 사용 (시, 분, 초)
LocalDateTime: LocalDate + LocalTime

ZonedDateTime, OffsetDateTime

ZonedDateTime
시간대를 고려한 날짜와 시간을 표현할때 사용한다. 시간대를 표현하는 타임존이 포함된다.

OffsetDateTime
시간대를 고려한 날짜 시간을 표현할 때 사용, 타임존은 없고, UTC로 부터 시간대 차이인 고정된 오프셋만 포함

Asia/Seoul 같은 타임존 안에는 일광 절약 시간제에 대한 정보와 UTC+9:00와 같은 UTC로 부터 시간 차이인 오프셋 정보를 모두 포함하고 있다.

일광 절약 시간제(DST, 썸머타임)을 알려면 타임존을 알아야 한다. 따라서 ZonedDateTime을 함께 처리한다. 반면에 타임존을 알 수 없는 OffSetDateTime 은 일광 절약 시간제를
는 일광 절약 시간제를 처리하지 못한다.

ZonedDateTime은 시간대를 고려해야 할 때 실제 사용하는 날짜와 시간 정보를 나타내는 데 더 적합하고,
OffSetDatTime은 UTC로부터의 고정된 오프셋만을 고려해야 할 때 유용하다

Instant
Instant는 UTC 협정시를 기준으로 하는 시간의 한 지점 Instant는 날짜와 시간을 나노초 정도 정밀표현, 쉽게 말해 Instant 내부에는 초 데이터만 들어있다.

Period. Duration

특정 시점의 시간

  • 이 프로젝트는 2013년 00월 00일 까지 완료
  • 다음 회의는 00시 00분에 진행

시간의 간격

  • 앞으로 4년은 더 공부 할 예정
  • 프로젝트 3개월 남음

기본 날짜와 시간 - LocalDatetime

가장 기본이 되는 날짜와 시간 클래스는 LocalDate, LocalTime, LocalDateTime 이다
LocalDate : 날짜만 표현할 때 사용한다. 년, 월, 일을 다룬다.
LocalTime : 시간만을 표현할 때 사용한다. 시, 분, 초를 다룬다.
LocalDateTime : LocalDate + LocalTime

LocalDate

public class LocalDateMain {
    public static void main(String[] args) {
        LocalDate nowDate = LocalDate.now();
        System.out.println("nowDate = " + nowDate);

        LocalDate ofDate = LocalDate.of(2024, 03, 05);
        System.out.println("ofDate = " + ofDate);

        //불변이기 때문에 반환값 받아야 한다
        LocalDate plusDay = ofDate.plusDays(10);
        System.out.println("plusDay = " + plusDay);
    }
}

now() : 현재 시간을 기준
of(...) : 특정 날짜를 기준
plusDays(): 특정일을 더한다

Localtime

public class LocalTimeMain {
    public static void main(String[] args) {
        LocalTime nowTime = LocalTime.now();
        LocalTime ofTime = LocalTime.of(9,10,30);

        System.out.println("nowTime = " + nowTime);
        System.out.println("ofTime = " + ofTime);

        LocalTime ofTimePlus = ofTime.plusSeconds(30);
        System.out.println("ofTimePlus = " + ofTimePlus);
    }
}

LocalDateTime

public class LocalDateTimeMain {
    public static void main(String[] args) {
        LocalDateTime nowDt = LocalDateTime.now();
        LocalDateTime ofDt = LocalDateTime.of(2016, 8, 16, 8, 10, 1);
        System.out.println("nowDt = " + nowDt);
        System.out.println("ofDt = " + ofDt);

        //날짜와 시간 분리
        LocalDate localDate = ofDt.toLocalDate();
        LocalTime localTime = ofDt.toLocalTime();
        System.out.println("localDate = " + localDate);
        System.out.println("localTime = " + localTime);

        //날짜와 시간 합체
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
        System.out.println("localDateTime = " + localDateTime);

        //계산
        LocalDateTime ofDtPlus = ofDt.plusDays(10000);
        System.out.println("ofDtPlus = " + ofDtPlus);

        LocalDateTime ofDtPlusYear = ofDt.plusYears(1);
        System.out.println("ofDtPlusYear = " + ofDtPlusYear);

        System.out.println("햔재 날짜 시간이 지정 날짜시간보다 이전인가?? " + nowDt.isBefore(ofDt));
        System.out.println("햔재 날짜 시간이 지정 날짜시간보다 이후인가?? " + nowDt.isAfter(ofDt));
        System.out.println("햔재 날짜 시간이 지정 날짜시간보다 같은가?? " + nowDt.isEqual(ofDt));
    }
}

LocalDate와 LocalTime을 toXxx() 메서드로 분리 가능

비교
isBefore() : 다른 날짜시간과 비교, 현재 날짜와 시간이 이전이라면 true
isAfter() : 다른 날짜시간과 비교, 현재 날짜와 시간이 이후라면 true
isEquals() : 다른 날짜시간과 시간적으로 동일한지 비교

타임존 -ZonedDateTime

타임존 목록 예시

 Europe/London
 GMT
 UTC
 US/Arizona -07:00
 America/New_York -05:00
 Asia/Seoul +09:00
 Asia/Dubai +04:00
 Asia/Istanbul +03:00
 Asia/Shanghai +08:00
 Europe/Paris +01:00
 Europe/Berlin +01:00

ZoneId

public class ZonedDateTimeMain {
    public static void main(String[] args) {
        ZonedDateTime nowZdt = ZonedDateTime.now();
        System.out.println("nowZdt = " + nowZdt);

        LocalDateTime ldt = LocalDateTime.of(2030,1,1,13,30,50);
        ZonedDateTime zdt1 = ZonedDateTime.of(ldt, ZoneId.of("Asia/Seoul"));
        System.out.println("zdt1 = " + zdt1);

        ZonedDateTime zdt2 = ZonedDateTime.of(2030,1,1,13,30,50,0, ZoneId.of("Asia/Seoul"));
        System.out.println("zdt2 = " + zdt2);

        ZonedDateTime utcZdt = zdt2.withZoneSameInstant(ZoneId.of("UTC"));
        System.out.println("utcZdt = " + utcZdt);
    }
}

ZonedDateTime: 시간대를 고려한 날짜와 시간을 표현할때 사용. 여기에는 시간대를 표현하는 타임존이 포함

+9:00은 UTC로 부터의 시간대 차이. 오프셋이라고 한다.

withZoneSameInstant(ZoneId) : 타임존을 변경한다. 타임존에 맞추어 시간도 함께 변경된다. 이 메서드를 사용하면 지금 다른 나라는 몇 시 인지 확인할 수 있다.

public class ZoneIdMain {
    public static void main(String[] args) {
        for (String availableZoneId : ZoneId.getAvailableZoneIds()) {
            ZoneId zoneId = ZoneId.of(availableZoneId);
            System.out.println("zoneId.getRules() = " + zoneId.getRules());
        }

        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println("zoneId = " + zoneId);

        ZoneId zoneId2 = ZoneId.of("Asia/Seoul");
        System.out.println("zoneId2 = " + zoneId2);
    }
}

ZoneId.systemDefault(): 시스템이 사용하는 기본 ZoneId를 반환한다.

ZoneId.of: 타임존을 직접 제공해서 ZoneId
를 반환한다.

OffsetDateTime

OffsetDateTime = LocalDateTime + ZoneOffset

OffsetDateTime: 시간대를 고려한 날짜와 시간을 표현할 때 사용. 여기에는 타임존은 없고, UTC로부터 시간대 차이인 고정된 오프셋만 포함

ZoneId가 없으므로 일광 절약 시간제가 적용X

public class OffSetDateTimeMain {
    public static void main(String[] args) {
        OffsetDateTime nowOdt = OffsetDateTime.now();
        System.out.println("nowOdt = " + nowOdt);

        LocalDateTime ldt = LocalDateTime.of(2030,1,1,13,30,50);
        System.out.println("ldt = " + ldt);
        OffsetDateTime odt = OffsetDateTime.of(ldt, ZoneOffset.of("+01:00"));
        System.out.println("odt = " + odt);
    }
}

ZonedDateTime vs OffsetDateTime
ZonedDateTime: 구체적 지역 시간대를 다룰때 사용, 일광 정략 시간을 자동으로 처리 -> 사용자 지정 시간대에 따른 시간 계산이 필요할때 적합

OffsetDateTime: UTC와 시간 차이만을 나타낼때 사용. 지역 시간대의 복잡성 고려X

기계 중심 시간 - Instant

Instant는 UTC를 기준으로 하는 시간의 한 지점. Instant는 날짜와 시간을 나노초로 정밀도로 표현

Epoch 시간
컴퓨터 시스탬에서 시간을 나타내는 방법중 하나. 이는 1970년 1월 1일 부터 현재 까지 경과한 시간을 초 단위로 표현

Instant 특징
장점

  • 시간대 독립성 : Instant는 UTC 기준, 시간대 영향을 받지 않는다.
  • 고정된 기준점 : 모든 Instant는 1970년 1월 1일 기준으로 하기 때문에 시간 계산 및 비교과 명확, 일관

단점

  • 사용 친화적 X : 기계적인 시간 처리에는 적합, 사람이 읽고, 이해하기는 부적합
  • 시간대 정보 부재 : 시간대 정보가 포함되어 있지 않아, 특정 지역의 날짜와 시간으로 변환 -> 추가적 작업 필요
public class InstantMain {
 public static void main(String[] args) {
 //생성
Instant now = Instant.now(); //UTC 기준
System.out.println("now = " + now);
 ZonedDateTime zdt = ZonedDateTime.now();
 Instant from = Instant.from(zdt);
 System.out.println("from = " + from);
 Instant epochStart = Instant.ofEpochSecond(0);
 System.out.println("epochStart = " + epochStart);
 //계산
Instant later = epochStart.plusSeconds(3600);
 System.out.println("later = " + later);
 //조회
long laterEpochSecond = later.getEpochSecond();
 System.out.println("laterEpochSecond = " + laterEpochSecond);
    }

from() : 다른 타입의 날짜와 시간을 기준, Instant를 생성. 참고로 Instant는 UTC 기준 -> LocalDateTime 사용 할 수 없음
ofEpochSecond() : 에포크 시간을 기준으로 Instant를 생성. 0초를 선택하면 애포크 시간인 1970년 1월 1일 생성

기간, 시간의 간격 - Duration, Period

public class DurationMain {
    public static void main(String[] args) {
        Duration duration = Duration.ofMillis(30);
        System.out.println("duration = " + duration);

        LocalTime lt = LocalTime.of(1, 0);
        System.out.println("lt = " + lt);

        LocalTime plusTime = lt.plus(duration);
        System.out.println("plusTime = " + plusTime);

        LocalTime start = LocalTime.of(9, 0);
        LocalTime end = LocalTime.of(10, 0);
        Duration between = Duration.between(start, end);
        System.out.println("근무시간 " + between.toHours() + " 시간 " + between.toMinutesPart() + " 분");

    }
}

Duration.between(start, end)

public class PeriodMain {
    public static void main(String[] args) {
        Period period = Period.ofDays(10);
        System.out.println("period = " + period);

        LocalDate curDate = LocalDate.of(2020,1,1);
        LocalDate plusDate = curDate.plus(period);
        System.out.println("curDate = " + curDate);
        System.out.println("plusDate = " + plusDate);

        LocalDate starDate = LocalDate.of(2023,1,1);
        LocalDate endDate = LocalDate.of(2024,1,1);

        Period between = Period.between(starDate, endDate);
        System.out.println("between.getMonths() = " + between.getMonths() + between.getDays());
    }
}

of(): 특정 기간을 지정해서 Period를 생성

 of(년, 월, 일)
 ofDays()
 ofMonths()
 Period
 ofYears()

기간 차이
Period.between(startDate, endDate) 특정 날짜의 차이를 구하면 Period 반환

날짜와 시간의 핵심 인터페이스

특정 시점의 시간 : Temporal 인터페이스를 구현.

구현으로는 LocalDateTime LocalDate LocalTime ZonedDateTime OffsetDateTime Instant가 있다.

시간의 간격 : TemporalAmount 인터페이스를 구현

TemporalAccessor 인터페이스
날짜와 시간을 읽기 위한 기본 인터페이스
특정 시점의 날짜와 시간 정보를 읽을 수 있는 최소한 기능

Temporal 인터페이스
TemporalAccessor의 하위 인터페이스로 날짜와 시간을 조작.

TemporalAmount 인터페이스
시간의 간격을 나태나며, 날짜와 시간 객체에 적용하며, 그 객체를 조정할 수 있다.

시간의 단위와 시간 필드
시간 단위를 의미하는 TemporalUnit과 시간의 각 필드를 뜻하는 TemporalField

시간의 단위 - TemporalUnit, ChronoUnit
TemporalUnit : 날짜와 시간을 측정하는 단위를 의미

ChronoUnit : 다양한 시간 단위를 제공

날짜 단위

public class ChronoUnitMain {
    public static void main(String[] args) {
        ChronoUnit[] unit = ChronoUnit.values();
        for (ChronoUnit chronoUnit : unit) {
            System.out.println("chronoUnit = " + chronoUnit);
        }

        System.out.println("HOURS : " + ChronoUnit.HOURS);
        System.out.println("HOURS.duration : " + ChronoUnit.HOURS.getDuration().getSeconds());
        System.out.println("DAYS : " + ChronoUnit.DAYS);
        System.out.println("DAYS.duration : " + ChronoUnit.DAYS.getDuration().getSeconds());

        LocalTime lt1 = LocalTime.of(1,10,0);
        LocalTime lt2 = LocalTime.of(1,20,0);

        long secondsBetween = ChronoUnit.SECONDS.between(lt1, lt2);
        System.out.println("secondsBetween = " + secondsBetween);

        long minutesBetween = ChronoUnit.MINUTES.between(lt1, lt2);
        System.out.println("minutesBetween = " + minutesBetween);
    }
}

시간 필드 - ChronoField

다양한 필드를 통해 특정 부분을 나타낸다.
여기에는 연도, 월, 일, 시간, 분 등이 포함된다.

TemproalField 인터페이스는 날짜와 시간을 나타내는데 사용.
주로 사용되는 구현체는 java.time.temporal.ChronoField 열거형으로 구현
ChronoField는 다양한 필드를 통해 날짜와 시간의 특정 부분을 나타낸다.
필드는 날짜와 시간 중에 특정 필드를 의미. 각각의 필드 항목은 다음을 참고
YEAR: 2024
MONTH_OF_YEAR: 8
DAY_OF_MONTH: 16

public class ChronoFieldMain {
    public static void main(String[] args) {
        ChronoField[] fields = ChronoField.values();

        for (ChronoField field : fields) {
            System.out.println(field + "field = " + field.range());
        }

        System.out.println("MONTH_OF_YEAR " + ChronoField.MONTH_OF_YEAR.range());
        System.out.println("DAY_OF_MONTH " + ChronoField.DAY_OF_MONTH.range());
    }
}

날짜와 시간 조회하고 조작

public class GetTimeMain {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2030,1,1,13,30,59);
        System.out.println("dt.get(ChronoField.YEAR) = " + dt.get(ChronoField.YEAR));
        System.out.println("dt.get(ChronoField.MONTH_OF_YEAR) = " + dt.get(ChronoField.MONTH_OF_YEAR));
        System.out.println("dt.get(ChronoField.DAY_OF_MONTH) = " + dt.get(ChronoField.DAY_OF_MONTH));
        System.out.println("dt.get(ChronoField.HOUR_OF_DAY) = " + dt.get(ChronoField.HOUR_OF_DAY));
        System.out.println("dt.get(ChronoField.MINUTE_OF_HOUR) = " + dt.get(ChronoField.MINUTE_OF_HOUR));
        System.out.println("dt.get(ChronoField.SECOND_OF_MINUTE) = " + dt.get(ChronoField.SECOND_OF_MINUTE));

        System.out.println("편의 메서드");
        System.out.println("dt.getYear() = " + dt.getYear());
        System.out.println("dt.getMonthValue() = " + dt.getMonthValue());
        System.out.println("dt.getHour() = " + dt.getHour());
        System.out.println("dt.getMinute() = " + dt.getMinute());
        System.out.println("dt.getSecond() = " + dt.getSecond());

        System.out.println("편의 메서드 X");
        System.out.println(dt.get(ChronoField.MINUTE_OF_DAY));
        System.out.println(dt.get(ChronoField.SECOND_OF_DAY));
    }
}

TemporalAccessor.get(TemporalField field)
LocalDateTime을 포함한 특정 시점의 시간을 제공하느 클래스는 모두 TemporalAccessor 인터페이스를 구현

TemporalAccessor는 특정 시점의 시간을 조회하는 기능

get(TemporalField field)을 호출할 때 어떤 날짜와 시간 필드를 조회할지 TemporalField의 구현인 ChronoField를 인수로 전달

편의 메서드 사용
get(TemporalField field)을 사용하면 코드가 길어지고 번거로움
dt.get(ChronoField.DAY_OF_MONTH)) -> dt.getDayOfMonth() 편의 메서드 제공

날짜와 시간 조작하기

날짜와 시간을 조작하려면 어떤 시간 단위(Unit)를 변경할 지 선택
날짜와 시간의 단위를 뜻하는 ChronoUnit이 사용된다.

public class ChangeTimePlusMain {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2018, 1, 1, 13, 30, 59, 59);
        System.out.println("dt = " + dt);

        LocalDateTime plus1 = dt.plus(10, ChronoUnit.YEARS);
        Period period = Period.ofYears(10);
        LocalDateTime pl2 = dt.plus(period);

        System.out.println("plus1 = " + plus1);
        System.out.println("pl2 = " + pl2);
    }
}

Temporal plus(long amountToAdd, TemporalUnit unit)

LocalDateTiem을 포함한 특정 시점의 시간을 제공하는 클래스는 모두 Temproal 인터페이스를 구현
Temporal은 특정 시점의 시간을 조작하는 기능
plus(long amountToAdd, TemporalUnit unit)를 호출할때 더하기 할 숫자와 시간의 단위를 전달. TemporalUnit의 구현이 ChronoUnit을 인수로 전달
불변이므로, 반환 값을 받아야 한다.

편의 메서드 사용
dt.plus(10, ChronoUnit.YEARS) -> dt.plusYears(10)

하지만 모든 시간 필드를 다 조회할 수 있는 것은 아니다.

public class IsSupportMain {
    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        int minute = now.get(ChronoField.SECOND_OF_MINUTE);
        System.out.println("minute = " + minute);
    }
}
 Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: 
Unsupported field: SecondOfMinute

LocalDate는 날짜 정보만 갖고 있고, 분에 대한 정보는 없다. 따라서 분에 대한 정보를 조회하려고 하면 예외 발생

TemporalAccessor
boolean isSupported(TemporalField field);

Temporal
boolean isSupported(TemporalUnit unit);
public class IsSupportMain2 {
    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        boolean supported = now.isSupported(ChronoField.SECOND_OF_MINUTE);
        System.out.println("supported = " + supported);
    }
}

LocalDate는 분의 초 필드를 지원하지 않으므로 ChronoField.SECOND_OF_MINUTE를 조회하면 false를 반환한다.

날짜와 시간 조회하고 조작하기 2

날짜와 시간을 조작하는 with 메서드

public class ChangeTimeWithMain {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2018,1,1,13,30,59);
        System.out.println("ldt = " + ldt);

        LocalDateTime changedDt1 = ldt.with(ChronoField.YEAR, 2020);
        System.out.println("changedDt1 = " + changedDt1);

        LocalDateTime changeDt2 = ldt.withYear(2020);
        System.out.println("changeDt2 = " + changeDt2);

        LocalDateTime with1 = ldt.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        System.out.println("ldt = " + ldt);
        System.out.println("with1 = " + with1);

        LocalDateTime with2 = ldt.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
        System.out.println("with2 = " + with2);
    }
}

Temporal.with()
날짜와 시간의 특정 필드의 값만 변경 가능.
불변이므로 반환 값을 받아야 한다.

편의 메서드
자주 사용하는 메서드는 편의 메서드가 제공
dt.with(ChronoField.YEAR, 2020) -> dt.withYear(2020)

TemporalAdjuster 사용
with는 아주 단순한 날짜만 변경 가능
\
DayOfWeek
월, 화, 수, 목, 금, 토, 일을 나타내는 열거형이다.

날짜와 시간 문자열 파싱과 포멧팅

포멧팅 : 날짜와 시간 데이터를 원하는 포멧 문자열로 변경 (Date -> String)
파싱 : 문자열을 날짜와 시간 데이터로 변경하는 것 (String -> Date)

public class FormattingMain1 {
    public static void main(String[] args) {
        //포멧팅 : 날짜를 문자로
        LocalDate date = LocalDate.of(2024,12,31);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
        String formattedDate = date.format(formatter);
        System.out.println("formattedDate = " + formattedDate);

        //파싱 : 문자를 날짜로
        String input = "2030년 01월 01일";
        LocalDate parsedDate = LocalDate.parse(input, formatter);
        System.out.println("parsedDate = " + parsedDate);
    }
}

LocalDate과 같은 날짜 객체를 원하는 형태의 문자로 변경하려면 DateTimeFormatter
를 사용하면 된다. 여기에 ofPattern()으로 원하는 포맷을 지정하면 된다. 여기서는 yyyy년 MM월 dd일포맷을 지정했다.


문자열을 날짜와 시간을 파싱

문자열을 읽어서 날짜와 시간 객체로 만드는 것을 파싱

 LocalDate.parse(input, formatter)
public class FormattingMain2 {
    public static void main(String[] args) {
        //포멧팅 : 날짜를 문자로
        LocalDateTime date = LocalDateTime.of(2024,12,31, 13, 30, 59 );
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = date.format(formatter);
        System.out.println("formattedDateTime = " + formattedDateTime);

        //파싱 : 문자를 날짜로
        String dateTimeString = "2030-01-01 11:30:00";
        LocalDateTime parsedDate = LocalDateTime.parse(dateTimeString, formatter);
        System.out.println("parsedDate = " + parsedDate);
    }
}

LocalDatetime과 같은 날짜와 시간 객체를 원하는 형태의 문자로 변경. DateTimeFormatter를 사용하면 된다. 여기에 ofPattern()으로 원하는 포멧을 지정

문자열을 날짜와 시간으로 파싱

 LocalDateTime.parse(dateTimeString, formatter)
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글