LocalDateTime으로 날짜를 구문 분석 / 형식화하는 방법은 무엇입니까? (자바 8)
Java 8 은 날짜 및 시간 작업을위한 새로운 java.time API를 추가했습니다 ( JSR 310 ).
날짜와 시간이 문자열로 있습니다 (예 :) "2014-04-08 12:30"
. LocalDateTime
주어진 문자열에서 인스턴스를 어떻게 얻을 수 있습니까?
LocalDateTime
객체 작업을 마친 후 : LocalDateTime
인스턴스를 위에 표시된 것과 같은 형식의 문자열로 다시 변환하려면 어떻게 해야합니까?
구문 분석 날짜 및 시간
LocalDateTime
문자열에서 객체 를 만들려면 정적 LocalDateTime.parse()
메서드를 사용할 수 있습니다 . 문자열과 DateTimeFormatter
매개 변수로 사용됩니다. 는 DateTimeFormatter
날짜 / 시간 패턴을 지정하는 데 사용됩니다.
String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
날짜 및 시간 형식
형식화 된 문자열을 LocalDateTime
객체로 만들려면 이 format()
방법을 사용할 수 있습니다 .
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"
에 상수로 미리 정의 된 몇 가지 일반적으로 사용되는 날짜 / 시간 형식이 있습니다 DateTimeFormatter
. 예를 들어 :를 사용 DateTimeFormatter.ISO_DATE_TIME
하여 LocalDateTime
인스턴스를 위에서 형식화 하면 string이 "1986-04-08T12:30:00"
됩니다.
parse()
및 format()
방법은 모든 날짜 / 시간 관련 개체 사용할 수 있습니다 (예를 들어, LocalDate
또는 ZonedDateTime
)
가 ISO-8601 형식 인 경우 패턴을 제공하지 않고 LocalDate.parse()
또는 LocalDateTime.parse()
에 사용할 수 있습니다 .String
String
예를 들어
String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
System.out.println("Date: " + aLD);
String strDatewithTime = "2015-08-04T10:11:30";
LocalDateTime aLDT = LocalDateTime.parse(strDatewithTime);
System.out.println("Date with Time: " + aLDT);
출력 ,
Date: 2015-08-04
Date with Time: 2015-08-04T10:11:30
DateTimeFormatter
다른 날짜 패턴을 처리해야하는 경우에만 사용하십시오 . 예를 들어 dd MMM uuuu 는 해당 월의 일 (2 자리), 해당 월 이름의 3 자 (Jan, Feb, Mar, ...)를 나타냅니다. 그리고 네 자리 연도 :
DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
String anotherDate = "04 Aug 2015";
LocalDate lds = LocalDate.parse(anotherDate, dTF);
System.out.println(anotherDate + " parses to " + lds);
산출
04 Aug 2015 parses to 2015-08-04
또한 DateTimeFormatter
객체가 양방향 이라는 것을 기억하십시오 . 입력과 형식 출력을 구문 분석 할 수 있습니다.
String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
System.out.println(aLD + " formats as " + dTF.format(aLD));
산출
2015-08-04 formats as 04 Aug 2015
(완전한 참조 포맷 및 구문 분석 DateFormatter에 대한 패턴의 목록 )
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
p pad next pad modifier 1
' escape for text delimiter
'' single quote literal '
[ optional section start
] optional section end
# reserved for future use
{ reserved for future use
} reserved for future use
위의 두 답변 모두 문자열 패턴에 관한 질문을 잘 설명합니다. 그러나 ISO 8601 로 작업하는 경우 DateTimeFormatter
LocalDateTime이 이미 준비되어 있으므로 적용 할 필요가 없습니다 .
LocalDateTime을 표준 시간대 ISO8601 문자열로 변환
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(ZoneOffset.UTC); //you might use a different zone
String iso8601 = zdt.toString();
ISO8601 문자열에서 LocalDateTime으로 다시 변환
String iso8601 = "2016-02-14T18:32:04.150Z";
ZonedDateTime zdt = ZonedDateTime.parse(iso8601);
LocalDateTime ldt = zdt.toLocalDateTime();
날짜와 시간이 포함 된 문자열을 특정 시점으로 구문 분석하는 것은 (Java에서 " Instant
"라고 함) 매우 복잡합니다. Java는 이것을 여러 번 반복하여 다루어 왔습니다. 최신 하나 java.time
와 java.time.chrono
, 커버 거의 모든 요구 (제외 시간 팽창 시킴 :)).
그러나 이러한 복잡성은 많은 혼란을 초래합니다.
날짜 구문 분석을 이해하는 핵심은 다음과 같습니다.
왜 Java가 날짜를 파싱하는 방법이 많은가?
- 시간을 측정하기위한 여러 시스템이 있습니다. 예를 들어, 역사적인 일본 달력은 각 황제 또는 왕조의 통치 기간에서 파생되었습니다. 그런 다음 UNIX 타임 스탬프가 있습니다. 다행히도 (비즈니스) 전 세계가 같은 것을 사용했습니다.
- 역사적으로 시스템은 여러 가지 이유로 전환되었습니다 . 예를 들어 율리우스 력 (Julian calendar)에서 1582 년 그레고리력 (Gregorian calendar)까지. 따라서 그 전에 '서부'날짜는 다르게 취급되어야한다.
- 물론 변경 사항은 한 번에 발생하지 않았습니다. 달력은 일부 종교와 유럽의 다른 지역의 헤드 쿼트에서 나왔기 때문에 다른식이 요법을 믿었습니다. 예를 들어 독일은 1700 년까지 전환하지 않았습니다.
... 그리고 왜 LocalDateTime
, ZonedDateTime
외. 너무 복잡한
있다 시간대 . 표준 시간대는 기본적으로 지구 표면의 "스트라이프" * [1] 이며, 권한을 가진 기관은 시간 오프셋이있는 시점과 동일한 규칙을 따릅니다. 여기에는 여름철 규칙이 포함됩니다.
시간대는 다양한 영역에 대해 시간이 지남에 따라 변경되며, 주로 누가 정복했는지에 따라 다릅니다. 한 시간대의 규칙도 시간이 지남에 따라 변경 됩니다.시간 오프셋이 있습니다. 표준 시간대는 "프라하"일 수 있지만 여름 시간 오프셋과 겨울 시간 오프셋이 있기 때문에 표준 시간대와 동일하지 않습니다.
시간대가 포함 된 타임 스탬프를 받으면 해당 연도의 일부에 따라 오프셋이 달라질 수 있습니다. 윤기 시간 동안 타임 스탬프는 두 번 다른 시간을 의미 할 수 있으므로 추가 정보 없이는 신뢰할 수 없습니다. 변환.
참고 : 타임 스탬프 란 "선택적으로 시간대 및 / 또는 시간 오프셋이있는 날짜 및 / 또는 시간을 포함하는 문자열"을 의미합니다.여러 시간대는 특정 기간 동안 동일한 시간 오프셋을 공유 할 수 있습니다. 예를 들어 서머 타임 오프셋이 적용되지 않은 경우 GMT / UTC 시간대는 "런던"시간대와 동일합니다.
좀 더 복잡하게 만들려면 (그러나 사용 사례에 그렇게 중요하지는 않습니다) :
- 과학자들은 지구의 역 동성을 관찰합니다. 이를 바탕으로 개별 연도 말에 초를 추가합니다. (그래서
2040-12-31 24:00:00
유효한 날짜 - 시간이 될 수 있습니다.) 이것은 메타 데이터를 정기적으로 업데이트해야 시스템이 바로 날짜 변환을 위해 사용하는. 예를 들어 Linux에서는 이러한 새 데이터를 포함하여 Java 패키지를 정기적으로 업데이트합니다. 업데이트가 항상 과거 및 미래 타임 스탬프에 대해 이전 동작을 유지하지는 않습니다. 따라서 일부 시간대 변경을 기준으로 두 타임 스탬프를 구문 분석 하면 서로 다른 버전의 소프트웨어에서 실행될 때 다른 결과를 얻을 수 있습니다. 이는 영향을받는 시간대와 다른 시간대를 비교하는 데에도 적용됩니다.
이로 인해 소프트웨어에 버그가 발생하면 UNIX 타임 스탬프 와 같이 복잡한 규칙이없는 타임 스탬프를 사용하는 것이 좋습니다.
미래 날짜의 경우 7로 인해 날짜를 정확하게 변환 할 수 없습니다. 예를 들어 현재 구문 분석은
8524-02-17 12:00:00
향후 구문 분석에서 몇 초가 걸릴 수 있습니다.
이를위한 JDK의 API는 현대의 요구와 함께 발전했습니다.
- 초기 Java 릴리스에는
java.util.Date
연도, 월, 일 및 시간이 있다고 가정하고 약간 순진한 접근 방식이있었습니다. 이것은 빨리 충분하지 않았다. - 또한 데이터베이스의 요구 사항은 매우 다르기 때문에
java.sql.Date
자체 제한 사항이 있지만 매우 초기 에 도입되었습니다. - 다른 캘린더와 시간대를 모두 다루지 않았으므로
Calendar
API가 도입되었습니다. - 이것은 여전히 표준 시간대의 복잡성을 다루지 않았습니다. 그러나 위 API의 혼합은 실제로 작업하기가 어려웠습니다. 따라서 Java 개발자가 글로벌 웹 응용 프로그램 작업을 시작하면서 JodaTime과 같은 대부분의 사용 사례를 대상으로하는 라이브러리가 빠르게 인기를 얻었습니다. JodaTime은 약 10 년 동안 사실상의 표준이었습니다.
- 그러나 JDK는 JodaTime과 통합되지 않았으므로 작업이 약간 번거로 웠습니다. 따라서 JSR-310 은이 문제에 접근하는 방법에 대한 매우 긴 토론 끝에 주로 JodaTime을 기반 으로 만들어졌습니다 .
Java에서 처리하는 방법 java.time
타임 스탬프를 구문 분석 할 유형 결정
타임 스탬프 문자열을 사용할 때는 어떤 정보가 들어 있는지 알아야합니다. 이것이 중요한 포인트입니다. 이 권한을 얻지 못하면 "즉시 만들 수 없음"또는 "영역 오프셋 누락"또는 "알 수없는 영역 ID"등과 같은 예외적 인 예외가 발생합니다.
- TemporalAccessor에서 OffsetDateTime을 얻을 수 없습니다
- TemporalAccessor에서 ZonedDateTime을 얻을 수 없습니다
- TemporalAccessor에서 LocalDateTime을 얻을 수 없습니다
- TemporalAccessor에서 인스턴트를 얻을 수 없습니다
날짜와 시간이 포함되어 있습니까?
시간 오프셋이 있습니까?
시간 오프셋이+hh:mm
부품입니다. 경우에 따라 '줄루 시간', 표준시 또는 그리니치 표준시+00:00
로 대체 될 수 있습니다 . 또한 시간대를 설정합니다. 이 타임 스탬프에는을 사용 합니다.Z
UTC
GMT
OffsetDateTime
시간대가 있습니까?
이 타임 스탬프에는을 사용ZonedDateTime
합니다.
영역은 다음 중 하나로 지정됩니다.- 이름 ( "프라하", "태평양 표준시", "PST") 또는
- "zone ID"( "America / Los_Angeles", "Europe / London")는 java.time.ZoneId로 표시됩니다 .
시간대 목록은 ICAAN이 지원 하는 "TZ 데이터베이스"에 의해 컴파일됩니다 .
ZoneId
의 javadoc 에 따르면 영역 ID를 어떻게 든 지정Z
하고 오프셋 으로 지정할 수 있습니다 . 이것이 실제 영역에 어떻게 매핑되는지 잘 모르겠습니다. TZ 만있는 타임 스탬프가 윤초 시간 오프셋 변경에 속하면 모호하며 해석이 적용ResolverStyle
됩니다 (아래 참조).이 둘 다 없으면 누락 된 컨텍스트가 가정되거나 무시됩니다. 그리고 소비자는 결정해야합니다. 따라서 누락 된 정보를 추가하여 구문 분석
LocalDateTime
하고 변환해야OffsetDateTime
합니다.- UTC 시간 이라고 가정 할 수 있습니다 . UTC 오프셋을 0 시간으로 추가하십시오.
- 전환이 발생한 시점 이라고 가정 할 수 있습니다 . 시스템 시간대를 추가하여 변환하십시오.
- 무시 하고 그대로 사용할 수 있습니다 . 예를 들어 두 번 비교하거나 빼는 데 유용합니다 (참조
Duration
). 모르거나 실제로 중요하지 않은 경우 (예 : 로컬 버스 일정).
부분 시간 정보
- 타임 스탬프가 포함 된 내용을 바탕으로, 당신이 취할 수
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, 또는YearMonth
그것에서.
전체 정보가 있으면를 얻을 수 있습니다 java.time.Instant
. 또한 내부적으로 OffsetDateTime
와 사이를 변환하는 데 사용됩니다 ZonedDateTime
.
그것을 파싱하는 방법을 알아 내십시오.
DateTimeFormatter
타임 스탬프 문자열과 형식을 문자열로 구문 분석 할 수 있는 광범위한 설명서 가 있습니다.
미리 만들어진 DateTimeFormatter
들 더보기 간략히 모든 표준 타임 스탬프 형식을 포함해야한다. 예를 들어, ISO_INSTANT
구문 분석 할 수 있습니다 2011-12-03T10:15:30.123457Z
.
특별한 형식이있는 경우 고유 한 DateTimeFormatter (파서이기도 함)를 만들 수 있습니다 .
private static final DateTimeFormatter TIMESTAMP_PARSER = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SX"))
.toFormatter();
의 소스 코드를보고를 사용하여 소스 코드를 DateTimeFormatter
작성하는 방법에 대해 영감을 얻는 것이 좋습니다 DateTimeFormatterBuilder
. 또한 ResolverStyle
파서가 형식 및 모호한 정보에 대해 LENIENT, SMART 또는 STRICT인지 여부를 제어 하는 방법도 살펴보십시오 .
임시 접근 자
이제 빈번한 실수는의 복잡성에 들어가는 것입니다 TemporalAccessor
. 개발자가 작업하는 방식에서 비롯된 것입니다 SimpleDateFormatter.parse(String)
. 오른쪽, DateTimeFormatter.parse("...")
당신을 제공합니다 TemporalAccessor
.
// No need for this!
TemporalAccessor ta = TIMESTAMP_PARSER.parse("2011-... etc");
그러나 이전 섹션의 지식을 갖추고 있으면 필요한 유형으로 편리하게 구문 분석 할 수 있습니다.
OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z", TIMESTAMP_PARSER);
실제로 DateTimeFormatter
어느 쪽도 필요하지 않습니다 . 구문 분석하려는 유형에는 parse(String)
메소드가 있습니다.
OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z");
에 관해서 TemporalAccessor
는 문자열에 어떤 정보가 있는지 모호하고 런타임에 결정하려는 경우 사용할 수 있습니다.
나는 당신의 영혼에 대한 이해의 빛을 비추기를 바랍니다 :)
참고 : java.time
Java 6 및 7 : BackTen-Backport 백 포트가 있습니다 . 안드로이드에는 ThreeTenABP가 있습니다.
[1] 그것들은 줄무늬가 아니라 이상한 극단도 있습니다. 예를 들어, 일부 인접한 태평양 섬 에는 +14 : 00 및 -11 : 00 시간대가 있습니다. 즉, 한 섬에는 5 월 1 일 오후 3시, 다른 섬에는 아직 4 월 12 일 오후 4시 30 분이 있습니다 (정확하게 계산 된 경우).
참고 URL : https://stackoverflow.com/questions/22463062/how-to-parse-format-dates-with-localdatetime-java-8
'Programing' 카테고리의 다른 글
github에서 Maven 저장소 호스팅 (0) | 2020.03.14 |
---|---|
각 줄의 시작 부분에 접두사 문자열 추가 (0) | 2020.03.14 |
텍스트가 한 줄 이상을 차지하지 못하게하는 방법은 무엇입니까? (0) | 2020.03.14 |
HTML에서 파일 입력에 값을 설정하는 방법은 무엇입니까? (0) | 2020.03.14 |
Amazon API Gateway에서 querystring 또는 route 매개 변수를 AWS Lambda로 전달하는 방법 (0) | 2020.03.14 |