2017-12-07 43 views
0

ZonedDateTime.now(ZoneOffset.of("+2:00")).minusDays(5)을 사용하여 만든 날짜가 있습니다. 이제 이것을 yyyy-MM-dd으로 포맷하고 싶습니다.Java 8+에서 DateTimeFormatter.ISO_LOCAL_DATE와 DateTimeFormatter.ofPattern ("yyyy-MM-dd")

Java 8 이상에서는 DateTimeFormatter.ISO_LOCAL_DATEDateTimeFormatter.ofPattern("yyyy-MM-dd")과 동일합니까?

출력이 동일하게 나타나고 문서 에서처럼 같아야합니다. 그러나, 그것의 "지방"부분은 나에게 쉼을 주었다. 알림 오프셋이 있고 ZonedDateTime을 사용하고 있습니다. 나는 당신이 오프셋 등을 다루고 있기 때문에 이러한 특별한 상황을 제외하고는 아무런 결함이 없다는 것을 확인하고 싶었습니다.

+3

[소스] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/time/format/DateTimeFormatter.java)를 확인할 수 없습니다. # DateTimeFormatter.0ISO_LOCAL_DATE) 아니면 테스트를 수행합니까? –

+1

첫 번째 Google 검색 결과 : https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_DATE –

+0

문서를 읽고 테스트했습니다. 출력물은 동일하게 보이며 문서에서 보듯이 동일해야합니다. 그러나, 그것의 "지방"부분은 나에게 쉼을 주었다. 알림 오프셋이 있고 ZonedDateTime을 사용하고 있습니다. 당신이 오프셋 등을 다루고 있기 때문에 나는이 이상한 상황을 제외하고는 "gotchas를 더 찾고 있었다"라고 생각합니다. " –

답변

3

5 일 전에 표시되는 날짜 - 시간을 포맷하려면 두 형식이 동일해야합니다. 서식 지정이나 구문 분석을 위해 모든 가능한 날짜에 대해 동등하지는 않습니다. 그들이 공통의 시대 ("AD")에서 년 동안 동일 보인다 포맷에 대한 그래서

-900000000-12-02 +900000001-12-02 Different 
-10000-12-02  +10001-12-02  Different 
-0002-12-02  0003-12-02  Different 
0000-12-02  0001-12-02  Different 
0001-12-02  0001-12-02  Same 
2017-12-02  2017-12-02  Same 
2099-12-02  2099-12-02  Same 
9999-12-02  9999-12-02  Same 
+10000-12-02  +10000-12-02  Same 
+900000000-12-02 +900000000-12-02 Same 

,하지만하지 :

DateTimeFormatter yyyyMmDd = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 
    int[] yearsToTest = { -900_000_000, -10_000, -2, 0, 1, 2017, 2099, 9999, 10_000, 900_000_000 }; 
    for (int year : yearsToTest) { 
     LocalDate date = LocalDate.of(year, Month.DECEMBER, 2); 
     String dateFormattedIso = date.format(DateTimeFormatter.ISO_LOCAL_DATE); 
     String dateFormattedYyyyMmDd = date.format(yyyyMmDd); 
     String diff = dateFormattedIso.equals(dateFormattedYyyyMmDd) ? "Same" : "Different"; 
     System.out.format("%-18s%-18s%s%n", dateFormattedIso, dateFormattedYyyyMmDd, diff); 
    } 

위의 조각 인쇄 :

의 그들을 밖으로 시도하자 공통의 시대가 오기 몇 해 전부터. yyyy은 연도 0이 없다고 간주하므로 LocalDate의 0이 연도 1로 렌더링됩니다.이 정보는 BCE로 이해되며이 정보는 인쇄되지 않습니다. ISO 포맷터는 부호와 함께 문자 그대로 1 년이 걸립니다.

yyyy 대신 uuuu을 사용하여 ISO_LOCAL_DATE의 동작을 얻을 수 있습니다.

여기에서 "로컬"은 시간대가없는 것을 의미하며, 이는 ZonedDateTime의 표준 시간대 정보가 인쇄되지 않음을 의미합니다. 어쨌든 기대하지 않았을 것입니다.

+1

또 다른 차이점은 관대 한 행동 일 수 있습니다. 필자가 아는 한, 상수 포매터는 엄격한 반면 패턴 기반 포매터는 구문 분석에 현명하다. 이는 "2017-02-29"(엄격 모드에서 거부되고 스마트 모드에서 조정 됨)와 같은 표현과 관련이 있습니다. –

+0

예, @MenoHochschild, 구문 분석의 차이점을 고려하지 않았지만, 분명히 일부가 있습니다. 이 방향으로 귀하의 기여에 감사드립니다. –

1

여기에서 ISO는 ISO-8601을 의미합니다. 해당 형식은 현재이며, 아마도 영구적으로 yyyy-MM-dd (현지 시간 이후로 시간대 없음)입니다. 하지만 스스로에게 물어보십시오. ISO 형식을 원하십니까? 아니면 yyyy-MM-dd를 원하십니까? 그들이 동일하다는 사실은 당신에게 중요하지 않습니다. 표준 표현을 원하거나 특정 표현을 원할 때 결정을 내리고있는 것입니다. 또는 질문은 "나는 ISO 포맷 날짜를 원한다면 나는 확신 할 수 없다. - 대답은 모든 것이 평등하다는 것을 나타냅니다.