나는 두 Date
s (예 : date1
및 date2
) 를 비교 하고 같은 날에 공유하는 boolean sameDay
두 가지 중 사실을 발견해야 Date
하며 그렇지 않은 경우에는 false입니다.
어떻게해야합니까? 여기 혼란의 소용돌이가있는 것 같습니다 … 가능한 경우 JDK 이외의 다른 종속성을 끌어 들이고 싶지 않습니다.
명확히하기 위해 : 경우 date1
와 date2
같은 년, 월, 일을 공유하고 sameDay
true, 그렇지 않으면 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 클래스에는 toInstant
java.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 답변을 살펴보십시오.