program tip

자바 : 날짜가 특정 범위 내에 있는지 어떻게 확인합니까?

radiobox 2020. 11. 23. 07:58
반응형

자바 : 날짜가 특정 범위 내에 있는지 어떻게 확인합니까?


시작일과 종료일이있는 일련의 범위가 있습니다. 날짜가 해당 범위 내에 있는지 확인하고 싶습니다.

Date.before () 및 Date.after ()는 사용하기가 약간 어색한 것 같습니다. 내가 정말로 필요한 것은 다음과 같은 의사 코드입니다.

boolean isWithinRange(Date testDate) {
    return testDate >= startDate && testDate <= endDate;
}

관련성이 있는지 확실하지 않지만 데이터베이스에서 가져 오는 날짜에는 타임 스탬프가 있습니다.


boolean isWithinRange(Date testDate) {
   return !(testDate.before(startDate) || testDate.after(endDate));
}

나에게 그렇게 어색하지 않은 것 같습니다. 대신 그렇게 썼습니다.

return testDate.after(startDate) && testDate.before(endDate);

따라서 testDate가 최종 사례 중 하나와 정확히 동일하더라도 작동합니다.


tl; dr

ZoneId z = ZoneId.of( "America/Montreal" );  // A date only has meaning within a specific time zone. For any given moment, the date varies around the globe by zone.
LocalDate ld = 
    givenJavaUtilDate.toInstant()  // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes.
                     .atZone( z )  // Adjust into the time zone in order to determine date.
                     .toLocalDate();  // Extract date-only value.

LocalDate today = LocalDate.now( z );  // Get today’s date for specific time zone.
LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 );  // Kwanzaa starts on Boxing Day, day after Christmas.
LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 );  // Kwanzaa lasts one week.
Boolean isDateInKwanzaaThisYear = (
    ( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after".
    &&
    today.isBefore( kwanzaaStop )  // Half-Open span of time, beginning inclusive, ending is *exclusive*.
)

반 개방

날짜-시간 작업은 일반적으로 "반 개방"방식을 사용하여 시간 범위를 정의합니다. 시작은 포괄적 이고 결말은 배타적 입니다. 따라서 월요일에 시작하는주는 다음 월요일까지 진행되지만 포함되지는 않습니다.

java.time

Java 8 이상에는 java.time 프레임 워크가 내장되어 있습니다. java.util.Date/.Calendar 및 SimpleDateFormat을 포함하여 오래된 문제가있는 클래스를 대체합니다. 성공적인 Joda-Time 라이브러리에서 영감을 얻었습니다. JSR 310에 의해 정의 됨. ThreeTen-Extra 프로젝트에 의해 확장 됨.

An Instant나노초 해상도 UTC 타임 라인의 한 순간입니다 .

Instant

java.util.Date 객체를 Instant 객체로 변환합니다.

Instant start = myJUDateStart.toInstant();
Instant stop = …

데이터베이스에서 JDBC를 통해 java.sql.Timestamp 객체를 가져 오는 경우 비슷한 방법으로 java.time.Instant로 변환합니다 . java.sql.Timestamp는 이미 UTC로되어 있으므로 시간대에 대해 걱정할 필요가 없습니다.

Instant start = mySqlTimestamp.toInstant() ;
Instant stop = …

비교를 위해 현재 순간을 가져옵니다.

Instant now = Instant.now();

isBefore, isAfter 및 equals 메서드를 사용하여 비교합니다.

Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;

LocalDate

시간이 아닌 날짜로만 작업하고 싶을 수 있습니다.

LocalDate클래스는 시간이 하루의 시간 영역없이없이 날짜 만 값을 나타냅니다.

LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;

현재 날짜를 가져 오려면 시간대를 지정하십시오. 주어진 순간에 오늘 날짜는 시간대에 따라 다릅니다. 예를 들어, 몬트리올보다 파리에서 새로운 날이 더 일찍 시작됩니다.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );

우리는 사용할 수 있습니다 isEqual, isBeforeisAfter비교하는 방법을. 날짜-시간 작업에서 우리는 일반적으로 시간 범위의 시작은 포함 하고 끝은 배타적 인 Half-Open 접근 방식을 사용합니다 .

Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;

Interval

ThreeTen-Extra 라이브러리를 프로젝트 에 추가하기로 선택한 경우 Interval클래스를 사용하여 시간 범위를 정의 할 수 있습니다 . 테스트에 그 클래스 이벤트 방법은 간격이있는 경우 포함 , 닿아 , 은 분리 장치 , 또는 중복 다른 날짜와 시간 / 간격.

Interval클래스에서 작동 Instant객체. Instant클래스는 나노초 (소수점의 최대 9 자리) 의 해상도로 타임 라인의 한 순간을 UTC나타냅니다 .

LocalDate를 가져올 시간대를 지정하여을 특정 순간, 즉 첫 번째 순간으로 조정할 수 있습니다 ZonedDateTime. 거기에서 우리는 Instant.

ZoneId z = ZoneId.of( "America/Montreal" );
Interval interval = 
    Interval.of( 
        start.atStartOfDay( z ).toInstant() , 
        stop.atStartOfDay( z ).toInstant() );
Instant now = Instant.now();
Boolean containsNow = interval.contains( now );

java.time 정보

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

java.time 클래스는 어디서 구할 수 있습니까?

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 가능성을 입증하는 근거가됩니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


그것이 올바른 방법입니다. 캘린더도 같은 방식으로 작동합니다. (귀하의 예를 바탕으로) 제가 제공 할 수있는 최선의 방법은 다음과 같습니다.

boolean isWithinRange(Date testDate) {
    return testDate.getTime() >= startDate.getTime() &&
             testDate.getTime() <= endDate.getTime();
}

Date.getTime ()은 1/1/1970 00:00:00 GMT 이후의 밀리 초 수를 반환하며 길어서 쉽게 비교할 수 있습니다.


Joda Time 사용을 고려하십시오 . 저는이 라이브러리를 좋아하고 기존 Java Date 및 Calendar 클래스 인 현재의 끔찍한 혼란을 대체하기를 바랍니다. 날짜 처리가 올바르게 완료되었습니다.

편집 : 더 이상 2009가 아니며 Java 8은 오랫동안 나왔습니다. Basil Bourque가 위에서 언급했듯이 Joda Time을 기반으로하는 Java 8의 내장 java.time 클래스를 사용하십시오. 이 경우 Period 클래스가 필요하며 여기 에 사용 방법에 대한 Oracle의 자습서 가 있습니다.


쉬운 방법은 1970 년 1 월 1 일 이후 날짜를 밀리 초로 변환 한 다음 (Date.getTime () 사용)이 값을 비교하는 것입니다.


날짜 경계가 어느 것인지 상관하지 않습니다.

Math.abs(date1.getTime() - date2.getTime()) == 
    Math.abs(date1.getTime() - dateBetween.getTime()) + Math.abs(dateBetween.getTime() - date2.getTime());

이렇게 사용할 수 있습니다

Interval interval = new Interval(date1.getTime(),date2.getTime());
Interval interval2 = new Interval(date3.getTime(), date4.getTime());
Interval overlap = interval.overlap(interval2);
boolean isOverlap = overlap == null ? false : true

This was clearer to me,

// declare calendar outside the scope of isWithinRange() so that we initialize it only once
private Calendar calendar = Calendar.getInstance();

public boolean isWithinRange(Date date, Date startDate, Date endDate) {

    calendar.setTime(startDate);
    int startDayOfYear = calendar.get(Calendar.DAY_OF_YEAR); // first day is 1, last day is 365
    int startYear = calendar.get(Calendar.YEAR);

    calendar.setTime(endDate);
    int endDayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
    int endYear = calendar.get(Calendar.YEAR);

    calendar.setTime(date);
    int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
    int year = calendar.get(Calendar.YEAR);

    return (year > startYear && year < endYear) // year is within the range
            || (year == startYear && dayOfYear >= startDayOfYear) // year is same as start year, check day as well
            || (year == endYear && dayOfYear < endDayOfYear); // year is same as end year, check day as well

}

  public class TestDate {

    public static void main(String[] args) {
    // TODO Auto-generated method stub

    String fromDate = "18-FEB-2018";
    String toDate = "20-FEB-2018";

    String requestDate = "19/02/2018";  
    System.out.println(checkBetween(requestDate,fromDate, toDate));
}

public static boolean checkBetween(String dateToCheck, String startDate, String endDate) {
    boolean res = false;
    SimpleDateFormat fmt1 = new SimpleDateFormat("dd-MMM-yyyy"); //22-05-2013
    SimpleDateFormat fmt2 = new SimpleDateFormat("dd/MM/yyyy"); //22-05-2013
    try {
     Date requestDate = fmt2.parse(dateToCheck);
     Date fromDate = fmt1.parse(startDate);
     Date toDate = fmt1.parse(endDate);
     res = requestDate.compareTo(fromDate) >= 0 && requestDate.compareTo(toDate) <=0;
    }catch(ParseException pex){
        pex.printStackTrace();
    }
    return res;
   }
 }

your logic would work fine . As u mentioned the dates ur getting from the database are in timestamp , You just need to convert timestamp to date first and then use this logic.

Also dont forget to check for null dates.

here m sharing a bit to convert from Timestamp to date.

public static Date convertTimeStamptoDate(String val) throws Exception {

    DateFormat df = null;
    Date date = null;

    try {
        df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        date = df.parse(val);
        // System.out.println("Date Converted..");
        return date;
    } catch (Exception ex) {
        System.out.println(ex);
        return convertDate2(val);
    } finally {
        df = null;
        date = null;
    }
}

참고URL : https://stackoverflow.com/questions/494180/java-how-do-i-check-if-a-date-is-within-a-certain-range

반응형