핵심 Java: 날짜 및 시간

34720 단어 corejava
Java8 이후 Oracle은 날짜/시간 API를 완전히 재구성했습니다.새 API는 이전 API를 대체해야 합니다.java.time 패키지에 있는 새 API는 라인이 안전합니다. 대부분의 새로운 종류는 변할 수 없기 때문에 구조 대상이 된 후에 수정할 수 없습니다.이것은 다중 스레드 환경에서 특히 유용하다. 왜냐하면 다중 스레드 환경에서 불변성, 스레드 방해와 데이터 손상 등 문제가 발생할 수 없기 때문이다.
이 문서는 새로운 API를 사용하는 방법을 보여 줍니다.

작성 날짜 및 시간
Java를 사용하면 정적 공장 방법을 사용하여 날짜와 시간을 만들 수 있습니다.구조 함수를 사용하여 날짜와 시간 대상을 만들 수 없습니다. (오래된 API로 만들 수 있지만, 해서는 안 됩니다.) 왜냐하면 이것은 개인적인 것이기 때문입니다.
창설 날짜와 시간은 간단합니다.작성한 날짜와 시간의 패턴을 확인할 수 있습니다.

로컬 날짜LocalDate의 고정 공장 운영 방식을 사용하여 다음 작업을 수행할 수 있습니다.
LocalDate now = LocalDate.now();
System.out.println(now);// 2020-02-21

LocalDate date = LocalDate.of(2020, 1, 23);
System.out.println(date);// 2020-01-23

LocalDate date2 = LocalDate.of(2020, Month.JANUARY, 23);
System.out.println(date2);// 2020-01-23
월별 색인은 1을 기초로 하는 것이므로 주의하십시오.

현지 시간
이와 유사하게 다음과 같이 LocalTime 객체를 만듭니다.
LocalTime now = LocalTime.now();
System.out.println(now);// 12:31:56.186

LocalTime midnight = LocalTime.of(23, 0);
System.out.println(midnight); // 23:00
두 번째 줄 출력 toStringLocalTime[hour:minutes:seconds.milliseconds]을 나타낸다

LocalDateTimeLocalDateTime류는 날짜와 시간의 조합을 나타낸다.다음과 같은 방법으로 만들 수 있습니다.
LocalDateTime now = LocalDateTime.now();
System.out.println(now);// 2020-02-21T12:46:09.950

LocalDateTime newYear = LocalDateTime.of(LocalDate.of(2021, 12, 31), LocalTime.of(11, 59));
System.out.println(newYear);// 2021-12-31T11:59
출력에서 날짜와 시간은 T으로 구분됩니다.

파티션 시간
특정 시간대의 날짜와 시간을 표시하려면 이 종류를 사용할 수 있습니다.예를 들면 다음과 같습니다.
ZonedDateTime usPacific = ZonedDateTime.now(ZoneId.of("US/Pacific"));
System.out.println(usPacific);// 2020-02-22T02:53:46.774455-08:00[US/Pacific]

ZonedDateTime now = ZonedDateTime.now();// 2020-02-22T11:53:46.778363+01:00[Africa/Casablanca]
System.out.println(now);
출력 형식은 LocalDateTimeZoneOffset으로 구성되어 있다.

조종 날짜와 시간
LocalDate date = LocalDate.of(2020, Month.JANUARY, 20);
System.out.println(date);// 2020–01–20

date = date.plusDays(1);
System.out.println(date);// 2020-01-21

date = date.plusWeeks(3);
System.out.println(date);// 2020-02-11

date = date.plusMonths(4);
System.out.println(date);// 2020-06-11

date = date.plusYears(10);
System.out.println(date);// 2030-06-11
이 방법들은 LocalDate 대상을 되돌려줍니다.따라서 다음과 같이 링크할 수 있습니다.
LocalDate date = LocalDate.of(2020, Month.JANUARY, 20)
        .plusDays(1).plusWeeks(3)
        .plusMonths(4).plusYears(10);
System.out.println(date);// 2030-06-11
같은 모델을 사용하면 LocalDate 방법으로 LocalDateTime, LocalTime, ZonedDateTimeminus###()에서 날짜/시간을 줄일 수 있다.

주기 및 기간

시기Period 클래스에서 마침표를 만듭니다.이런 것은 연, 월, 일 단위의 시간량을 나타낸다.이러한 예는 Period을 만드는 일반적인 방법을 보여 줍니다.
Period threeDays = Period.ofDays(3);
System.out.println(threeDays);// P3D

Period threeWeeks = Period.ofWeeks(3);
System.out.println(threeWeeks);// P21D

Period threeMonths = Period.ofMonths(3);
System.out.println(threeMonths);// P3M

Period threeYears = Period.ofYears(3);
System.out.println(threeYears);// P3Y

Period threeYearsAndFourMonthsAndTwoDays = Period.of(3, 4, 2);
System.out.println(threeYearsAndFourMonthsAndTwoDays);// P3Y4M2D
이런 정적 공장 방법은 자명하지 않다.그것들은 변할 수 없는 Period 실례를 만들었다.
출력에서 알파벳 P은 시기를 대표하고 Y은 연도를 대표하며 M은 월을 대표하고 D은 날을 대표한다.LocalDate을 만들 때 Period의 예에서 볼 수 있는 것처럼 링크 방법은 정적이기 때문에 링크하면 의외의 행동을 얻을 수 없습니다.
Period oneWeekAndADay = Period.ofDays(1).ofWeeks(1);
System.out.println(oneWeekAndADay); // unexpected result: P7D
Period은 특정 객체에 사용할 수 없습니다.몇 가지 코드를 살펴보겠습니다.
Period period = Period.ofDays(1);
LocalTime time = LocalTime.of(6, 15);
time.plus(period); // UnsupportedTemporalTypeException

기간Duration 클래스에서 지속 시간 표를 만들 수 있습니다.이런 것은 초와 나초 단위의 시간량을 나타낸다.분 및 시간 등의 기간 단위 표현을 추가로 사용할 수도 있습니다.이러한 예는 Duration을 만드는 일반적인 방법을 보여 줍니다.
Duration oneNano = Duration.ofNanos(1);
System.out.println(oneNano);// PT0.000000001S

Duration oneMilli = Duration.ofMillis(1);
System.out.println(oneMilli);// PT0.001S

Duration oneSeconds = Duration.ofSeconds(1);
System.out.println(oneSeconds);// PT1S

Duration oneMinute = Duration.ofMinutes(1);
System.out.println(oneMinute);// PT1M

Duration oneHour = Duration.ofHours(1);
System.out.println(oneHour);// PT1H

Duration oneDay = Duration.ofDays(1);
System.out.println(oneDay);// PT24H
또는 다음과 같은 방법으로 Duration을 생성할 수 있습니다.
Duration fiveHours = Duration.of(5, ChronoUnit.HOURS);
System.out.println(fiveHours);
이 방법은 5를 양과 단위로 지속 시간을 측정한다.

사용 순간Instant 클래스에서 순간을 만듭니다.이 유형은 1970년 1월 1일(1970-01-01T00:00:00Z) 이후 GMT 타임라인의 한 순간점을 대표하고 EPOCH이라고도 부른다.프로그램에서 이벤트 시간 스탬프를 기록하고 싶을 때 도움이 될 수 있습니다.이러한 예는 Instant을 만드는 일반적인 방법을 보여 줍니다.
Instant now = Instant.now();
System.out.println(now);//2020-02-25T11:14:46.032856Z

ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("US/Eastern"));
System.out.println(zonedDateTime);// 2020-02-25T06:27:27.572624-05:00[US/Eastern]
Instant now2 = Instant.from(zonedDateTime);
System.out.println(now2);// 2020-02-25T11:14:46.055857Z

Instant instant = Instant.parse("2010-01-20T11:33:45Z");
System.out.println(instant);// 2010-01-20T11:33:45Z

Instant epoch = Instant.ofEpochMilli(0);
System.out.println(epoch);// 1970-01-01T00:00:00Z
toString의 출력은 ISO-8601 표준을 따른다는 것을 주의하십시오.
보시다시피 자바가 Instant.from(zonedDateTime);을 호출할 때 Instant 대상에서 ZonedDateTime 대상을 만들고 미국/동부 시간대에서 GMT로 시간을 전환합니다.
이와 유사하게, 이 종류는 각종 실례를 조작하는 방법을 제공했다.예를 들면 다음과 같습니다.
Instant tenMinutesLater = Instant.now().plus(10, ChronoUnit.MINUTES);
System.out.println(tenMinutesLater);// print 10 minutes later from the current time

해석 및 서식 적용

이루다
JDK는 시간 기반의 대상을 해석하고 포맷하는 새로운 API를 제공합니다. DateTimeFormatter 패키지의 java.time.format을 사용하면 날짜와 시간을 해석하고 포맷할 수 있습니다.대부분의 다른 새로운 날짜/시간 API 클래스와 유사하게 DateTimeFormatter은 변경이 불가능하므로 스레드가 안전합니다.
이러한 클래스는 시간 기반 객체를 포맷하여 표시할 수 있는 format 방법을 제공합니다.예를 들어, 이 코드는 미리 정의된 포맷 프로그램을 사용하여 날짜와 시간을 포맷합니다.
LocalDate date = LocalDate.of(2020, Month.MARCH, 17);
LocalTime time = LocalTime.of(9, 15, 45);
LocalDateTime dateTime = LocalDateTime.of(date, time);

System.out.println(
dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));// 2020-03-17T09:15:45

System.out.println(
date.format(DateTimeFormatter.ISO_LOCAL_DATE));// 2020-03-17

System.out.println(
time.format(DateTimeFormatter.ISO_LOCAL_TIME));// 09:15:45

DateTimeFormatter shortF = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
System.out.println(shortF.format(dateTime));// 3/17/20, 9:15 AM

DateTimeFormatter mediumF = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
System.out.println(mediumF.format(dateTime));// Mar 17, 2020, 9:15:45 AM
또한 DateTimeFormatter.ofPattern 방법을 사용하여 사용자 정의 포맷 프로그램 객체를 정의할 수도 있습니다.
LocalDate date = LocalDate.of(2020, Month.MARCH, 17);
LocalTime time = LocalTime.of(9, 15, 45);
LocalDateTime dateTime = LocalDateTime.of(date, time);

DateTimeFormatter f = DateTimeFormatter.ofPattern("dd-MMMM-yyyy | hh:mm");
System.out.println(dateTime.format(f));// 17-March-2020 | 09:15
ofPattern 방법 매개 변수에 사용되는 문법에 대해 더 알고 싶으면 반드시 reference documentation을 보십시오.

해석
현재 당신은 시제에 기반한 클래스를 문자열로 바꾸는 방법을 알고 있습니다. parse 방법을 사용하여 다른 방향으로 바꾸는 방법을 보십시오.
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd MM yyyy");
LocalDate date = LocalDate.parse("25 03 2020", f);
LocalTime time = LocalTime.parse("09:30");

System.out.println(date);// 2020-03-25
System.out.println(time);// 09:30
LocalDate.parse(“25 03 2020“, f)은 사용자 정의 포맷 프로그램의 대상을 사용하여 텍스트 문자열을 분석하여 LocalDate으로 되돌려줍니다.반면 LocalTime.parse(“09:30”)은 기본 형식 설정 프로그램(DateTimeFormatter.ISO_LOCAL_TIME)을 사용하여 텍스트 문자열을 분석하고 LocalTime으로 되돌려줍니다

Java 8 이전 날짜 및 시간 일별
자바8에 앞서 개발자는 Date류를 사용했는데 날짜와 시간을 나타낸다.날짜나 시간을 따로 받을 수 없고 Date류에 묶여 있다.개발자는 더 이상 이런 종류를 사용해서는 안 된다. 보시다시피 더 좋은 방법이 있다.이러한 존재는 향후 호환성을 지원하기 위한 것이다.Date류의 또 다른 단점은 가변적이라는 것이다.따라서 여러 라인에서 이러한 실례에 접근할 때 데이터 손상과 의외의 행위를 피하기 위해 그것들에 대한 접근을 동기화해야 한다.
남아 있는 항목에 오래된 API가 있을 수 있습니다.그 구조 함수를 호출하여 만든 날짜: Date date = new Date()date은 현재 날짜/시간을 표시합니다.클래스 Calendar을 사용하여 특정 날짜를 지정할 수 있습니다.
Calendar cal = Calendar.getInstance();
cal.set(2020, 0, 23);
Date d = cal.getTime();
System.out.println(d);// Wed Jan 01 11:36:37 WET 2020
이 오래된 API가 새 API에 비해 얼마나 지루한지 보실 수 있습니다.월간 지수는 1이 아니라 0을 기초로 한다는 점에서 곤혹스럽다.새 API의 인덱스는 하나에 기반합니다.

마무리
이 글에서 나는 왜 새로운 날짜/시간 API를 사용해야 하는지, 그것을 어떻게 사용하는지, 날짜와 시간을 포맷하고 해석하는지 보여 주려고 한다.Java8 이전에 날짜/시간을 처리하는 방법
만약 네가 이 문장이 유용하다고 생각한다면, 너는 지금 어떻게 해야 할지 안다."박수"단추를 누르면 더 많은 글과 강좌를 얻을 수 있습니다.

좋은 웹페이지 즐겨찾기