sourcecode

날짜가 일정 범위 내에 있는지 확인하려면 어떻게 해야 하나요?

copyscript 2022. 9. 12. 11:44
반응형

날짜가 일정 범위 내에 있는지 확인하려면 어떻게 해야 하나요?

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

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);

따라서 test Date가 최종 케이스 중 하나와 정확하게 일치해도 동작합니다.

dr;dr

ZoneId z = ZoneId.of( "America/Montreal" );  // A date only has meaning within a specific time zone. At 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*.
)

하프 오픈

날짜 작업에서는 일반적으로 "Half-Open" 접근 방식을 사용하여 시간 범위를 정의합니다.시작은 포함이고 끝은 제외입니다.따라서 월요일로 시작하는 일주일은 다음 월요일까지 이어지지만 포함되지는 않습니다.

java.time

Java 8 이후에는 프레임워크가 내장되어 있습니다.다음과 같은 성가신 오래된 클래스를 대체합니다.java.util.Date/.Calendar ★★★★★★★★★★★★★★★★★」SimpleDateFormat조다 타임JSR 310입니다.쓰리텐 엑스트라

는 타임라인 상의 분해능이 나노초인 UTC의 순간입니다.

Instant

★★★을 변환java.util.Date즉석

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

「 」를 취득했을 .java.sql.TimestampJDBC를 통해 데이터베이스에서 객체를 java.time으로 변환합니다.비슷한 방법으로 순간적으로.ajava.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

아마도 당신은 하루 중 시간이 아닌 날짜로만 작업하기를 원할 것입니다.

LocalDatezone을 하지 않는 만의 값을 나타냅니다.class는 time-of-day 및 time zone을 하지 않습니다.

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

현재 날짜를 가져오려면 표준 시간대를 지정하십시오.어느 시점에서든, 오늘의 날짜는 시간대별로 다릅니다.예를 들어, 파리에서는 몽트렐보다 새로운 날이 일찍 밝는다.

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

, 그럼 이렇게 .isEqual,isBefore , , , , 입니다.isAfter비교 방법.날짜 작업에서는 일반적으로 시간 범위의 시작은 포함시키고 끝은 배타적인 하프 오픈 방식을 사용합니다.

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

Interval

프로젝트에 ThreeTen-Extra 라이브러리를 추가하도록 선택한 경우 클래스를 사용하여 시간 범위를 정의할 수 있습니다.이 클래스는 간격에 다른 날짜/간격이 포함되는지, 인접하는지, 포함되는지 또는 겹치는지 테스트하는 메서드를 제공합니다.

Interval을 받다Instant물건들.클래스는 타임라인상의 순간을 UTC로 나노초(10진수의 최대 9자리)의 분해능으로 나타냅니다.

을 할 수 있어요.LocalDate의 첫 으로, 「시간대」를 지정해 「를 취득합니다.ZonedDateTime하면 UTC로 수 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 프레임워크는 Java 8 이후에 포함되어 있습니다.이러한 클래스는 , 및 등 문제가 많은 오래된 레거시 날짜 시간 클래스를 대체합니다.

현재 유지 보수 모드에 있는 Joda-Time 프로젝트는 클래스로의 마이그레이션을 조언합니다.

자세한 내용은 Oracle 자습서를 참조하십시오.또한 Stack Overflow를 검색하여 많은 예와 설명을 확인하십시오.사양은 JSR 310입니다.

『 』의 java.time수??

  • 자바 SE 8 및 SE 9 이후
  • 붙박이.
  • 번들 구현이 포함된 표준 Java API의 일부입니다.
  • Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되어 있습니다.
  • 자바 SE 6 및 SE 7
  • 부분 much 의 java.time기능은 ThreeTen-Backport에서 Java 6 및7로 백포트됩니다.
  • 안드로이드
  • 쓰리텐ABP 프로젝트는 특히 ThreeTen-Backport(상기)를 Android용으로 채택하고 있습니다.
  • 사용방법을 참조해 주세요.

ThreeTen-Extra 프로젝트는java.time추가 클래스가 있습니다.이 프로젝트는 미래에 추가될 수 있는 것을 증명하는 기반입니다.java.time. , , , 과 같은 유용한 클래스가 있습니다.

그게 맞는 방법이에요.달력은 같은 방식으로 작동합니다.(당신의 예에 따라) 제가 제공할 수 있는 최선의 방법은 다음과 같습니다.

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

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

Joda Time 사용을 고려합니다.저는 이 라이브러리가 마음에 들고, 그것이 기존의 Java Date와 Calendar 클래스인 현재의 끔찍한 혼란을 대체하기를 바랍니다.날짜 처리가 제대로 되었습니다.

편집: 지금은 2009년이 아닙니다.Java 8은 오랫동안 출시되지 않았습니다.위에서 Basil Bourque가 언급한 바와 같이 Joda Time에 기반한 Java 8의 빌트인 java.time 클래스를 사용합니다.이 경우 Period 클래스가 필요하며, 사용 방법에 대한 Oracle 튜토리얼이 여기에 있습니다.

부터Java 8

메모: 1개만 제외하고 모두Date의 컨스트럭터는 사용되지 않습니다.대부분의 경우Date의 메서드는 권장되지 않습니다.REF: 날짜: 사용되지 않는 메서드.전부, 하지만Date::from(Instant)스태틱 메서드는 권장되지 않습니다.

그래서 자바8은 다음 명령어를 사용하는 것을 고려하기 때문에Instant (불변, 스레드 세이프, 윤초 인식) 타입이 아닌Date.참조: 즉석

  static final LocalTime MARKETS_OPEN = LocalTime.of(07, 00);
  static final LocalTime MARKETS_CLOSE = LocalTime.of(20, 00);

    // Instant utcTime = testDate.toInstant();
    var bigAppleTime = ZonedDateTime.ofInstant(utcTime, ZoneId.of("America/New_York"));

포함 범위 내:

    return !bigAppleTime.toLocalTime().isBefore(MARKETS_OPEN)
        && !bigAppleTime.toLocalTime().isAfter(MARKETS_CLOSE);

제외 범위 내:

    return bigAppleTime.toLocalTime().isAfter(MARKETS_OPEN)
        && bigAppleTime.toLocalTime().isBefore(MARKETS_CLOSE);

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

와 포괄적으로 비교하고 싶다면LocalDate이 코드를 사용합니다.

LocalDate from = LocalDate.of(2021,8,1);
LocalDate to = LocalDate.of(2021,8,1);
LocalDate current = LocalDate.of(2021,8,1);

boolean isDateInRage = ( ! (current.isBefore(from.minusDays(1)) && current.isBefore(to.plusDays(1))) );

내가 보기엔 이게 더 분명했어

// 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

}

케이스를 커버하기 위해 -> 범위 시작일과 종료일, 그리고 일정 부분 범위 내에 있는 날짜 목록이 있습니다(중복).

테스트 대상 솔루션:

/**
 * Check has any of quote work days in provided range.
 *
 * @param startDate inclusively
 * @param endDate   inclusively
 *
 * @return true if any in provided range inclusively
 */
public boolean hasAnyWorkdaysInRange(LocalDate startDate, LocalDate endDate) {
    if (CollectionUtils.isEmpty(workdays)) {
        return false;
    }

    LocalDate firstWorkDay = getFirstWorkDay().getDate();
    LocalDate lastWorkDay = getLastWorkDay().getDate();

    return (firstWorkDay.isBefore(endDate) || firstWorkDay.equals(endDate))
            && (lastWorkDay.isAfter(startDate) || lastWorkDay.equals(startDate));
}

어느 날짜의 경계는 상관없다.

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
  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;
   }
 }

날짜가 시작 날짜와 동일한 경우 새 솔루션 추가:

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

솔루션

return testDate.equals(startDate) || (testDate.after(startDate) && 
testDate.before(endDate)) || testDate.equals(endDate);
    public boolean isBetween(LocalDate target, LocalDate min, LocalDate max) {
    if (target == null || min == null || max == null) {
        throw new IllegalArgumentException("paramettres can't be null");
    }

    return target.compareTo(min) >= 0 && target.compareTo(max) <= 0;
}

해결책은 날짜를 after와 before 방법으로 확인하는 것입니다.testDate와 endDate가 같은 날일 때 endDate, testDate.before(endDate)가 false를 반환하는 것을 고려해야 할 경우 "apache commons.lang.time" 패키지를 사용하여 확인할 수 있습니다.Date Utils)

import org.apache.commons.lang.time.DateUtils;

boolean isWithinRange(Date testDate) {
    return   testDate.after(startDate) && (testDate.before(endDate) || DateUtils.isSameDay(testDate, endDate));
}

당신의 논리는 정상적으로 동작할 것입니다.데이터베이스에서 취득한 날짜가 타임스탬프 안에 있다고 언급했듯이 타임스탬프를 먼저 날짜로 변환한 후 이 논리를 사용하면 됩니다.

또한 null 날짜를 확인하는 것도 잊지 마십시오.

여기에서는 타임스탬프에서 날짜로 변환하기 위한 비트를 공유합니다.

public static Date convertTimeStamptoDate(String val)가 예외 {를 발생시킵니다.

    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;
    }
}

구글 구아바

Range.closed(start, end)
            .isConnected(Range.closed(now, now));

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

반응형