Programing

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

lottogame 2020. 4. 16. 08:13
반응형

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


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

어떻게해야합니까? 여기 혼란의 소용돌이가있는 것 같습니다 ... 가능한 경우 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));

private boolean isSameDay(Date date1, Date date2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        boolean sameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
        boolean sameMonth = calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
        boolean sameDay = calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
        return (sameDay && sameMonth && sameYear);
    }

자바 8

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

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

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


안드로이드 사용자 :

DateUtils.isToday(dateMilliseconds)주어진 날짜가 현재 날짜인지 여부를 확인 하는 사용할 수 있습니다 .

API 참조 : https://developer.android.com/reference/android/text/format/DateUtils.html#isToday(long)


Binil Thomas 솔루션 외에

public static boolean isOnSameDay(Timestamp... dates) {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
    String date1 = fmt.format(dates[0]);
    for (Timestamp date : dates) {
        if (!fmt.format(date).equals(date1)) {
            return false;
        }
    }
    return true;
}

용법

    isOnSameDay(date1,date2,date3 ...);
//or 
    isOnSameDay(mydates);

Kotlin 개발자의 경우 형식화 된 문자열 접근 방식을 비교 한 버전입니다.

val sdf = SimpleDateFormat("yyMMdd")
if (sdf.format(date1) == sdf.format(date2)) {
    // same day
}

가장 좋은 방법은 아니지만 짧고 작동합니다.


SimpleDateFormat에 의존하지 않고 SimpleDateFormat 솔루션과 동일한 논리를 적용 할 수 있습니다.

date1.getFullYear()*10000 + date1.getMonth()*100 + date1.getDate() == 
date2.getFullYear()*10000 + date2.getMonth()*100 + date2.getDate()

참고 : https://stackoverflow.com/questions/2517709/comparing-two-java-util-dates-to-see-if-they-are-in-the-same-day

반응형