[java] 두 개의 java.util.Date를 비교하여 같은 날인지 확인하십시오.

나는 두 Dates (예 : date1date2) 를 비교 하고 같은 날에 공유하는 boolean sameDay두 가지 중 사실을 발견해야 Date하며 그렇지 않은 경우에는 false입니다.

어떻게해야합니까? 여기 혼란의 소용돌이가있는 것 같습니다 … 가능한 경우 JDK 이외의 다른 종속성을 끌어 들이고 싶지 않습니다.

명확히하기 위해 : 경우 date1date2같은 년, 월, 일을 공유하고 sameDaytrue, 그렇지 않으면 false이다. 나는 이것이 시간대에 대한 지식이 필요하다는 것을 알고 있습니다 … 시간대를 통과하는 것이 좋을 것이지만 행동이 무엇인지 아는 한 GMT 또는 현지 시간으로 살 수 있습니다.

다시 명확히하기 위해 :

date1 = 2008 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
  => sameDate = true

date1 = 2009 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
  => sameDate = false

date1 = 2008 Aug 03 12:00:00
date2 = 2008 Jun 03 12:00:00
  => sameDate = false



답변

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);
boolean sameDay = cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) &&
                  cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);

“당일”은 다른 시간대가 포함될 수있을 때 들리는 것처럼 단순한 개념이 아닙니다. 위의 코드는 두 날짜 모두에 대해 컴퓨터에서 사용되는 시간대를 기준으로 날짜를 계산합니다. 이것이 필요하지 않은 경우 Calendar.getInstance()“당일”의 의미를 정확히 결정한 후 관련 시간대를 통화로 전달해야합니다.

그리고 예, Joda Time LocalDate은 모든 것을 훨씬 깨끗하고 쉽게 만들 것입니다 (시간대와 관련된 동일한 어려움이있을지라도).


답변

어때요?

SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
return fmt.format(date1).equals(fmt.format(date2));

필요한 경우 시간대를 SimpleDateFormat으로 설정할 수도 있습니다.


답변

“apache commons lang”패키지를 사용하여이 작업을 수행합니다 (즉, org.apache.commons.lang.time.DateUtils ).

boolean samedate = DateUtils.isSameDay(date1, date2);  //Takes either Calendar or Date objects


답변

각 날짜에 대한 율리우스 일 수 를 계산 한 후 다음을 비교 하여 달력을 사용할 때 외부 종속성 및 성능 저하를 피할 수 있습니다 .

public static boolean isSameDay(Date date1, Date date2) {

    // Strip out the time part of each date.
    long julianDayNumber1 = date1.getTime() / MILLIS_PER_DAY;
    long julianDayNumber2 = date2.getTime() / MILLIS_PER_DAY;

    // If they now are equal then it is the same day.
    return julianDayNumber1 == julianDayNumber2;
}


답변

조다 타임

의존성을 추가하는 것에 관해서는 java.util.Date & .Calendar가 실제로 너무 나빠서 새 프로젝트에 가장 먼저하는 일은 Joda-Time 라이브러리를 추가하는 것입니다. Java 8에서는 Joda-Time에서 영감을 얻은 새로운 java.time 패키지를 사용할 수 있습니다.

Joda-Time의 핵심은 DateTime클래스입니다. java.util.Date와 달리 지정된 시간대 ( DateTimeZone)를 이해합니다 . juDate에서 변환 할 때 영역을 지정하십시오.

DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );

LocalDate

두 개의 날짜 시간이 같은 날짜에 도달하는지 확인하는 한 가지 방법은 LocalDate개체 로 변환하는 것 입니다.

해당 변환은 지정된 시간대에 따라 다릅니다. LocalDate객체 를 비교하려면 동일한 구역으로 변환해야합니다.

다음은 약간의 유틸리티 방법입니다.

static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
    LocalDate ld1 = new LocalDate( dt1 );
    // LocalDate determination depends on the time zone.
    // So be sure the date-time values are adjusted to the same time zone.
    LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
    Boolean match = ld1.equals( ld2 );
    return match;
}

첫 번째 DateTime 객체의 시간대를 사용해야한다고 가정하지 않고 시간대를 지정하는 또 다른 인수가 더 좋습니다.

static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
    LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
    // LocalDate determination depends on the time zone.
    // So be sure the date-time values are adjusted to the same time zone.
    LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
    return ld1.equals( ld2 );
}

문자열 표현

또 다른 방법은 각 날짜-시간의 날짜 부분에 대한 문자열 표현을 만든 다음 문자열을 비교하는 것입니다.

다시 한 번 지정된 시간대가 중요합니다.

DateTimeFormatter formatter = ISODateTimeFormat.date();  // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() )  );
Boolean match = s1.equals( s2 );
return match;

시간의 스팬

일반화 된 솔루션은 시간 범위를 정의한 후 범위에 대상이 있는지 묻습니다. 이 예제 코드는 Joda-Time 2.4에 있습니다. “자정”관련 클래스는 더 이상 사용되지 않습니다. 대신이 withTimeAtStartOfDay방법을 사용하십시오 . Joda-Time은 간격, 기간 및 기간 등 다양한 방법으로 시간 범위를 나타내는 세 가지 클래스를 제공합니다.

범위의 시작이 포함되고 끝이 독점 인 “하프-오픈”접근 방식을 사용합니다.

대상의 시간대는 간격의 시간대와 다를 수 있습니다.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );

java.time

Java 8 이상에는 java.time 프레임 워크 가 제공됩니다 . Joda-Time에서 영감을 얻었으며 JSR 310에서 정의했으며 ThreeTen-Extra 프로젝트에서 확장되었습니다. 튜토리얼 참조 .

Joda-Time의 제작자는 우리 모두에게 편리한 시간에 java.time으로 이동하도록 지시했습니다. 그 동안 Joda-Time은 적극적으로 유지 관리되는 프로젝트로 계속 진행됩니다. 그러나 향후 작업은 Joda-Time이 아닌 java.time 및 ThreeTen-Extra에서만 발생할 것으로 예상합니다.

간단히 말해서 java.time을 요약하면… An Instant은 타임 라인의 순간입니다 (UTC). 시간대 ( ZoneId)를 적용하여 ZonedDateTime개체 를 가져옵니다 . 날짜 – 시간의 막연한 부정 아이디어를 얻을, 타임 라인을 이동하려면 “로컬”클래스를 사용 : LocalDateTime, LocalDate,LocalTime .

이 Answer의 Joda-Time 섹션에서 논의 된 논리는 java.time에 적용됩니다.

이전 java.util.Date 클래스에는 toInstantjava.time으로 변환하기위한 새로운 메소드가 있습니다.

Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.

날짜를 결정하려면 시간대가 필요합니다.

ZoneId zoneId = ZoneId.of( "America/Montreal" );

해당 시간대 개체를에 적용하여 Instant를 얻습니다 ZonedDateTime. 이를 통해 LocalDate날짜 (시간, 분 등이 아닌)를 비교하는 것이 목적이므로 날짜 전용 값 (a )을 추출합니다 .

ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );

java.util.Date비교에 필요한 두 번째 객체 와 동일하게 수행하십시오 . 대신 현재 순간을 사용하겠습니다.

ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );

특수한 isEqual방법을 사용하여 동일한 날짜 값을 테스트 하십시오 .

Boolean sameDate = localDate1.isEqual( localDate2 );


답변

여기에 표시된 대로 날짜를 Java 8 java.time.LocalDate 변환
하십시오 .

LocalDate localDate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate localDate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

// compare dates
assertTrue("Not on the same day", localDate1.equals(localDate2));


답변

자바 8

프로젝트에서 Java 8을 사용하고 비교 java.sql.Timestamp하는 경우 LocalDate클래스를 사용할 수 있습니다 .

sameDate = date1.toLocalDateTime().toLocalDate().equals(date2.toLocalDateTime().toLocalDate());

를 사용하는 경우 java.util.Date덜 모호한 Istvan 답변을 살펴보십시오.