[java] 자바 날짜 대 달력

누군가 현재의 “모범 사례” DateCalendar유형에 대해 조언 해 주시겠습니까 ?

새 코드를 작성할 때 항상 선호 Calendar하는 것이 가장 좋습니까 Date, 아니면 Date더 적합한 데이터 유형이있는 환경 이 있습니까?



답변

날짜는 더 간단한 클래스이며 주로 이전 버전과의 호환성을 위해 존재합니다. 특정 날짜를 설정하거나 날짜를 산술해야하는 경우 달력을 사용하십시오. 캘린더는 현지화도 처리합니다. Date의 이전 날짜 조작 기능은 더 이상 사용되지 않습니다.

개인적으로 나는 선택이있을 때 긴 시간 (또는 적절하게 긴) 또는 달력으로 밀리 초 단위의 시간을 사용하는 경향이 있습니다.

Date와 Calendar는 모두 변경 가능하므로 API에서 사용할 때 문제가 발생하는 경향이 있습니다.


답변

새 코드를 작성하는 가장 좋은 방법은 (정책에서 타사 코드를 허용하는 경우) Joda Time 라이브러리 를 사용하는 것 입니다.

DateCalendar 모두 디자인 문제가 너무 많아서 새로운 코드를위한 좋은 솔루션이 아닙니다.


답변

  • Date그리고 Calendar정말 같은 기본 개념 (모두가 나타내고있는 시간 인스턴트를 하고 기초 주위에 래퍼 long값).

  • 요일과 시간과 같은 것들에 대한 구체적인 사실을 제공하는 것처럼 보이지만 Calendar실제로Date 는 그것 보다 훨씬 더 깨진 것이라고 주장 할 수 있습니다.timeZone 속성 하면 콘크리트가 블랑 망으로 변합니다! 이러한 이유로 인해 객체는 실제로 월-일 또는 시간 저장소로 유용하지 않습니다 .

  • 사용 Calendar주어 졌을 때, 계산기로 단지 DateTimeZone객체, 당신을 위해 계산을 할 것입니다. 응용 프로그램에서 속성 입력에 사용하지 마십시오.

  • 사용하다 SimpleDateFormat 과 함께 TimeZoneDate디스플레이 문자열을 생성 할 수 있습니다.

  • Joda-Time이 모험적이라고 생각되면 불필요하게 복잡한 IMHO이며 곧 JSR-310 날짜 API로 대체됩니다.

  • 나는 자신의 YearMonthDay클래스 를 굴리는 것이 어렵지 않다고 대답했다.이 클래스 Calendar는 날짜 계산을 위해 사용 됩니다. Joda-Time (및 JSR-310 )이 대부분의 유스 케이스에 대해 너무 복잡하기 때문에 제안에 대해 하향 투표를 받았지만 여전히 유효하다고 생각합니다 .


답변

날짜는 날짜 개체를 저장하는 데 가장 좋습니다. 그것은 지속되는 것, 직렬화 된 것입니다 …

달력은 날짜를 조작하는 데 가장 좋습니다.

참고 : Date는 변경 가능하므로 스레드로부터 안전하지 않기 때문에 Date보다 java.lang.Long을 선호하는 경우가 있습니다. Date 객체에서 setTime () 및 getTime ()을 사용하여 둘 사이를 전환합니다. 예를 들어, 응용 프로그램의 상수 날짜 (예 : 1970/01/01 0 또는 2099/12/31로 설정 한 적용 END_OF_TIME; null 값을 시작 시간 및 종료 시간으로 대체하는 데 특히 유용합니다. SQL이 널 (null)과 같이 고유하기 때문에 데이터베이스에 유지하는 경우).


답변

가능한 경우 일반적으로 Date를 사용합니다. 변경 가능하지만 실제로는 더 이상 사용되지 않습니다. 결국 기본적으로 날짜 / 시간을 나타내는 long을 감 쌉니다. 반대로 값을 조작 해야하는 경우 캘린더를 사용합니다.

이 방법으로 생각할 수 있습니다. toString () 메서드를 사용하여 쉽게 조작하고 문자열로 변환 할 수있는 문자열이 필요한 경우에만 StringBuffer를 사용합니다. 같은 방법으로, 나는 임시 데이터를 조작해야 할 경우에만 달력을 사용합니다.

모범 사례를 위해 도메인 모델 외부에서 가능한 한 불변의 객체를 사용하는 경향이 있습니다 . 부작용의 가능성을 크게 줄이고 JUnit 테스트 대신 컴파일러가 수행합니다. 개인 결승 을 만들어이 기술을 사용합니다클래스에서 필드를 .

그리고 StringBuffer 유추로 돌아갑니다. 다음은 달력과 날짜를 변환하는 방법을 보여주는 코드입니다.

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);


답변

Dates 불변 시점으로 사용되어야한다. Calendars는 변경 가능하며 다른 날짜와 협업하기 위해 다른 클래스와 협력해야하는 경우 전달 및 수정 될 수 있습니다. 에 그들과 유사 고려 String하고StringBuilder 당신은 나는 그들이 사용되어야한다 고려 방법을 이해하는 것입니다.

(그리고 예, Date는 실제로 기술적으로 변경 불가능하다는 것을 알고 있지만 의도는 변경 불가능해서는 안되며 더 이상 사용되지 않는 메소드를 호출하는 것이 없다면 그렇게하는 것입니다.)


답변

tl; dr

현재의 “모범 사례”에 대해 조언 Date하고Calendar

항상 찬성 Calendar하는 것이 최선입니까?Date

이러한 레거시 클래스는 완전히 피하십시오 . 대신 java.time 클래스를 사용하십시오 .

  • UTC 로 잠시 사용 하십시오.Instant
    Date )
  • 특정의 순간 시간대 , 사용 (현대 상응하는 )ZonedDateTime
    GregorianCalendar
  • UTC에서 특정 오프셋 에서 잠시 동안 사용하십시오 (레거시 클래스에서는 동일하지 않음)OffsetDateTime
  • 시간대 또는 오프셋을 알 수없는 날짜-시간 (순간이 아님)의 경우 (레거시 클래스에서는 동일하지 않음)LocalDateTime

최신 및 기존 Java의 모든 날짜-시간 유형 표

세부

Ortomala 의해 답변을 Lokni 현대 사용하는 것이 좋습니다 할 권리 java.time에 오히려 귀찮은 오래된 기존의 날짜 – 시간 수업 (보다 클래스를 Date, Calendar등). 그러나 그 대답은 잘못된 클래스를 동등한 것으로 제안합니다 (해답에 대한 내 의견 참조).

java.time 사용

java.time 클래스는 레거시 날짜-시간 클래스 (야간 차이)에 비해 크게 개선되었습니다. 구식 수업은 잘 설계되지 않았고 혼란스럽고 번거 롭습니다. 가능할 때마다 이전 수업을 피해야합니다. 그러나 이전 / 새로 변환하거나 이전 / 새로 변환해야 할 때 새 메소드를 호출하여 이전에 추가 할 수 있습니다 클래스를 클래스에 .

변환에 대한 자세한 내용은 내 Answer and nifty 다이어그램 을 다른 질문으로 변환하십시오. java.util.Date를 “java.time”유형으로 변환 하시겠습니까?.

검색 스택 오버플로는 java.time 사용에 관한 수백 가지의 질문과 답변을 제공합니다. 그러나 여기에 간단한 시놉시스가 있습니다.

Instant

으로 현재 순간을 가져옵니다 Instant. 이 Instant클래스는 나노초 의 해상도 (소수점의 최대 9 자리)로 UTC 의 타임 라인에서 순간을 나타냅니다 .

Instant instant = Instant.now();

ZonedDateTime

특정 지역의 벽시계 시간 의 렌즈를 통해 동일한 동시 모멘트 를 보려면 시간대 ( )를 적용하여 를 얻습니다 .ZoneIdZonedDateTime

시간대

지정 적절한 시간대 이름 의 형식 continent/region예컨대, America/Montreal, Africa/Casablanca, 또는 Pacific/Auckland. 표준 시간대 가 아니EST 거나 표준화되지 않았으며 고유하지 않은 3-4 문자 약어를 사용하지 마십시오 .IST

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();

오프셋

시간대는 해당 지역의 UTC에서 오프셋 변경 내역입니다 . 그러나 때로는 전체 영역이없는 오프셋 만 제공됩니다. 이 경우 OffsetDateTime클래스를 사용하십시오 .

ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );

단순한 오프셋을 사용하는 것보다 시간대를 사용하는 것이 좋습니다.

LocalDateTime

Local…수업 에서 “지역” 은 특정 지역이 아닌 모든 지역을 의미 합니다 . 따라서 이름은 반 직관적 일 수 있습니다.

LocalDateTime, LocalDateLocalTime오프셋 또는 시간대에 대한 정보가 의도적으로 없습니다. 그들이 그래서 하지 실제 순간을 표현, 그들은 하지 타임 라인에 포인트. 의심이나 혼란에 사용하는 경우 ZonedDateTime보다는 LocalDateTime. 더 많은 논의를 위해 검색 스택 오버플로.

날짜-시간 객체를 해당 값을 나타내는 문자열과 혼동하지 마십시오. 문자열을 구문 분석하여 날짜-시간 객체를 얻을 수 있으며 날짜-시간 객체에서 문자열을 생성 할 수 있습니다. 그러나 문자열은 날짜-시간 자체가 아닙니다.

java.time 클래스에서 기본적으로 사용되는 표준 ISO 8601 형식에 대해 학습 합니다.


java.time에 대하여

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 – 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310입니다 입니다.

JDBC 4.2 이상 과 호환 되는 JDBC 드라이버를 사용하면 데이터베이스와 직접 java.time 객체를 교환 할 수 있습니다. 문자열이나 java.sql. * 클래스가 필요하지 않습니다.

java.time 클래스는 어디서 구할 수 있습니까?

Java 또는 Android 버전과 함께 사용할 java.time 라이브러리 표

ThreeTen – 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .