자바 날짜 대 달력
누군가 현재의 "모범 사례" Date
와 Calendar
유형에 대해 조언 해 주시겠습니까 ?
새 코드를 작성할 때 항상 선호 Calendar
하는 것이 가장 좋습니까 Date
, 아니면 Date
더 적합한 데이터 유형이있는 환경 이 있습니까?
날짜는 더 간단한 클래스이며 주로 이전 버전과의 호환성을 위해 존재합니다. 특정 날짜를 설정하거나 날짜를 산술해야하는 경우 달력을 사용하십시오. 캘린더는 현지화도 처리합니다. Date의 이전 날짜 조작 기능은 더 이상 사용되지 않습니다.
개인적으로 나는 선택이있을 때 긴 시간 (또는 적절하게 긴) 또는 달력으로 밀리 초 단위의 시간을 사용하는 경향이 있습니다.
날짜와 달력은 모두 변경 가능하므로 API에서 사용할 때 문제가 발생하는 경향이 있습니다.
새 코드를 작성하는 가장 좋은 방법은 (정책에서 타사 코드를 허용하는 경우) Joda Time 라이브러리 를 사용하는 것 입니다.
Date 와 Calendar 모두 디자인 문제가 너무 많아서 새로운 코드를위한 좋은 솔루션이 아닙니다.
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 클래스는 기존 날짜-시간 클래스 (야간 차이)에 비해 크게 개선되었습니다. 구식 수업은 잘 설계되지 않았고 혼란스럽고 번거 롭습니다. 가능할 때마다 이전 수업을 피해야합니다. 그러나 이전 / 새로 변환하거나 이전 / 새로 변환해야하는 경우 새 메소드 add를 호출하여 이전 클래스에 추가 할 수 있습니다.
변환에 대한 자세한 내용은 내 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
. 절대로 같은 3-4 문자 약어를 사용하지 EST
또는 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
, 그리고 더 .
Java 8에서는 새로운 java.time 패키지를 사용해야합니다.
개체는 변경할 수 없으며 시간대와 일광 절약 시간이 고려됩니다.
다음 과 같이 ZonedDateTime
오래된 java.util.Date
객체 에서 객체를 만들 수 있습니다 .
Date date = new Date();
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
나는 항상 Joda-time을 옹호 합니다 . 이유는 다음과 같습니다.
- API는 일관되고 직관적입니다. java.util.Date/Calendar API와 달리
- java.text.SimpleDateFormat 등과 달리 스레딩 문제로 고통받지 않습니다 (표준 날짜 / 시간 형식이 스레드로부터 안전하지 않다는 것을 깨닫지 못하는 것과 관련된 많은 클라이언트 문제가 있음을 보았습니다)
- 새로운 Java 날짜 / 시간 API ( JSR310 , Java 8 용으로 예약 됨) 의 기초입니다. 따라서 핵심 Java API가 될 API를 사용하게됩니다.
편집 : Java 8로 마이그레이션 할 수 있다면 Java 8과 함께 도입 된 Java 날짜 / 시간 클래스가 선호되는 솔루션입니다.
약간 늦었지만 Java에는 JDK 8에 새로운 Date Time API가 있습니다. JDK 버전을 업그레이드하고 표준을 채택 할 수 있습니다. 더 이상 지저분한 날짜 / 달력, 더 이상 타사 항아리가 없습니다.
날짜를 다시 개발해야합니다. 긴 interger가 아닌 년, 월, 일,시, 분, 초를 별도의 필드로 보유해야합니다. 이 날짜와 연결된 달력 및 시간대를 저장하는 것이 좋을 수도 있습니다.
자연스러운 대화에서 2013 년 11 월 1 일 오후 1시 (미국 시간)에 약속을 설정하면 날짜 / 시간입니다. 캘린더가 아닙니다. 따라서 Java에서도 이와 같이 대화 할 수 있어야합니다.
Date가 긴 정수 (1970 년 1 월 1 일 이후 밀리 초 등)로 저장된 경우 현재 날짜 계산은 달력에 따라 다릅니다. 다른 달력은 다른 날짜를 제공합니다. 이는 절대 시간 (예 : 빅뱅 후 1 조 초)을 제공 할 것으로 예상됩니다. 그러나 종종 우리는 연도, 월 등을 캡슐화하는 객체와 같은 편리한 대화 방법이 필요합니다.
이 두 가지 목표를 조정하기 위해 Java에 새로운 발전이 있는지 궁금합니다. 어쩌면 내 자바 지식이 너무 오래되었을 수도 있습니다.
Btw "date"는 일반적으로 "폐기 / 더 이상 사용되지 않음"으로 태그됩니다 (정확히 이유를 모르겠습니다) . Java 에 대해 작성된 내용은 다음과 같습니다. Java : Date 생성자가 더 이상 사용되지 않는 이유는 무엇입니까?
새로운 Date (int year, int month, int day) 를 통한 생성자 만의 문제 인 것처럼 보이며 권장되는 방법은 Calendar를 통해 매개 변수를 별도로 설정하는 것입니다 .. ( Calendar cal = Calendar.getInstance (); )
시간 이동과 같은 날짜에 특정 작업이 필요할 때 캘린더를 사용하지만 날짜는 필요에 맞게 날짜를 형식화해야 할 때 유용하다는 것을 알았습니다. 최근에 로케일에는 유용한 작업과 메소드가 많이 있음을 발견했습니다. 나는 지금 로케일을 사용하고 있습니다!
참고 URL : https://stackoverflow.com/questions/1404210/java-date-vs-calendar
'development' 카테고리의 다른 글
MVC 3에서 현재 페이지 URL을 얻는 방법 (0) | 2020.03.01 |
---|---|
{} 또는 new Object ()를 사용하여 JavaScript로 빈 객체를 만드시겠습니까? (0) | 2020.02.29 |
Windows cmd에서 사용자 입력을 요청하고 다른 명령에서 결과를 사용하려면 어떻게합니까? (0) | 2020.02.29 |
Windows 8 런타임 (WinRT / Windows Store 앱 / Windows 10 Universal App)은 Silverlight 및 WPF와 어떻게 다릅니 까? (0) | 2020.02.29 |
gdb에서 긴 문자열의 전체 값을 어떻게 인쇄합니까? (0) | 2020.02.29 |