누군가 현재의 “모범 사례” Date
와 Calendar
유형에 대해 조언 해 주시겠습니까 ?
새 코드를 작성할 때 항상 선호 Calendar
하는 것이 가장 좋습니까 Date
, 아니면 Date
더 적합한 데이터 유형이있는 환경 이 있습니까?
답변
날짜는 더 간단한 클래스이며 주로 이전 버전과의 호환성을 위해 존재합니다. 특정 날짜를 설정하거나 날짜를 산술해야하는 경우 달력을 사용하십시오. 캘린더는 현지화도 처리합니다. Date의 이전 날짜 조작 기능은 더 이상 사용되지 않습니다.
개인적으로 나는 선택이있을 때 긴 시간 (또는 적절하게 긴) 또는 달력으로 밀리 초 단위의 시간을 사용하는 경향이 있습니다.
Date와 Calendar는 모두 변경 가능하므로 API에서 사용할 때 문제가 발생하는 경향이 있습니다.
답변
새 코드를 작성하는 가장 좋은 방법은 (정책에서 타사 코드를 허용하는 경우) Joda Time 라이브러리 를 사용하는 것 입니다.
답변
-
Date
그리고Calendar
정말 같은 기본 개념 (모두가 나타내고있는 시간 인스턴트를 하고 기초 주위에 래퍼long
값). -
요일과 시간과 같은 것들에 대한 구체적인 사실을 제공하는 것처럼 보이지만
Calendar
실제로Date
는 그것 보다 훨씬 더 깨진 것이라고 주장 할 수 있습니다.timeZone
속성 하면 콘크리트가 블랑 망으로 변합니다! 이러한 이유로 인해 객체는 실제로 월-일 또는 시간 저장소로 유용하지 않습니다 . -
사용
Calendar
주어 졌을 때, 계산기로 단지Date
와TimeZone
객체, 당신을 위해 계산을 할 것입니다. 응용 프로그램에서 속성 입력에 사용하지 마십시오. -
사용하다
SimpleDateFormat
과 함께TimeZone
와Date
디스플레이 문자열을 생성 할 수 있습니다. -
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);
답변
Date
s 불변 시점으로 사용되어야한다. Calendar
s는 변경 가능하며 다른 날짜와 협업하기 위해 다른 클래스와 협력해야하는 경우 전달 및 수정 될 수 있습니다. 에 그들과 유사 고려 String
하고StringBuilder
당신은 나는 그들이 사용되어야한다 고려 방법을 이해하는 것입니다.
(그리고 예, Date는 실제로 기술적으로 변경 불가능하다는 것을 알고 있지만 의도는 변경 불가능해서는 안되며 더 이상 사용되지 않는 메소드를 호출하는 것이 없다면 그렇게하는 것입니다.)
답변
tl; dr
현재의 “모범 사례”에 대해 조언
Date
하고Calendar
항상 찬성
Calendar
하는 것이 최선입니까?Date
이러한 레거시 클래스는 완전히 피하십시오 . 대신 java.time 클래스를 사용하십시오 .
- UTC 로 잠시 사용 하십시오.
Instant
Date
) - 특정의 순간 시간대 , 사용 (현대 상응하는 )
ZonedDateTime
GregorianCalendar
- UTC에서 특정 오프셋 에서 잠시 동안 사용하십시오 (레거시 클래스에서는 동일하지 않음)
OffsetDateTime
- 시간대 또는 오프셋을 알 수없는 날짜-시간 (순간이 아님)의 경우 (레거시 클래스에서는 동일하지 않음)
LocalDateTime
세부
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
특정 지역의 벽시계 시간 의 렌즈를 통해 동일한 동시 모멘트 를 보려면 시간대 ( )를 적용하여 를 얻습니다 .ZoneId
ZonedDateTime
시간대
지정 적절한 시간대 이름 의 형식 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
, LocalDate
및 LocalTime
오프셋 또는 시간대에 대한 정보가 의도적으로 없습니다. 그들이 그래서 하지 실제 순간을 표현, 그들은 하지 타임 라인에 포인트. 의심이나 혼란에 사용하는 경우 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 클래스는 어디서 구할 수 있습니까?
- 자바 SE 8 , 자바 SE 9 , 나중에
- 내장.
- 번들로 구현 된 표준 Java API의 일부입니다.
- Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되었습니다.
- Java SE 6 및 Java SE 7
- 대부분의 java.time 기능은 ThreeTen-Backport 에서 Java 6 & 7로 백 포트됩니다. .
- 기계적 인조 인간
- java.time 클래스의 최신 버전의 Android 번들 구현.
- 이전 Android의 경우 ThreeTenABP 프로젝트 는 위에서 언급 한 ThreeTen-Backport를 채택합니다 . ThreeTenABP 사용 방법…을 참조하십시오 .
ThreeTen – 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval
, YearWeek
, YearQuarter
, 그리고 더 .