development

자바 날짜 대 달력

big-blog 2020. 2. 29. 15:27
반응형

자바 날짜 대 달력


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

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


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

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

날짜와 달력은 모두 변경 가능하므로 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

세부

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

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

시간대

지정 적절한 시간대 이름 의 형식 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, 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 클래스는 어디서 구할 수 있습니까?

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을 옹호 합니다 . 이유는 다음과 같습니다.

  1. API는 일관되고 직관적입니다. java.util.Date/Calendar API와 달리
  2. java.text.SimpleDateFormat 등과 달리 스레딩 문제로 고통받지 않습니다 (표준 날짜 / 시간 형식이 스레드로부터 안전하지 않다는 것을 깨닫지 못하는 것과 관련된 많은 클라이언트 문제가 있음을 보았습니다)
  3. 새로운 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



반응형