자바 : 날짜가 특정 범위 내에 있는지 어떻게 확인합니까?
시작일과 종료일이있는 일련의 범위가 있습니다. 날짜가 해당 범위 내에 있는지 확인하고 싶습니다.
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
, isBefore
및 isAfter
비교하는 방법을. 날짜-시간 작업에서 우리는 일반적으로 시간 범위의 시작은 포함 하고 끝은 배타적 인 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 클래스는 어디서 구할 수 있습니까?
- Java SE 8 및 SE 9 이상
- 내장.
- 번들로 구현 된 표준 Java API의 일부입니다.
- Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되었습니다.
- Java SE 6 및 SE 7
- java.time 기능의 대부분은 ThreeTen-Backport의 Java 6 및 7로 백 포트됩니다 .
- 기계적 인조 인간
- ThreeTenABP의 프로젝트는 적응 ThreeTen - 백 포트 특히 안드로이드에 대한 (위에서 언급).
- 사용 방법…을 참조하십시오 .
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
'program tip' 카테고리의 다른 글
다른 사람의 Github에서 리포지토리를 복제하여 내 Github의 리포지토리로 푸시 (0) | 2020.11.23 |
---|---|
ASP.NET GridView에서 부울을 Yes / No로 변환 할 수 있습니까? (0) | 2020.11.23 |
개체가 형식이 아닌지 확인 (! = "IS"에 해당)-C # (0) | 2020.11.23 |
Visual Studio 내에서 LARGEADDRESSAWARE를 설정할 수 있습니까? (0) | 2020.11.23 |
내 Android 장치에 특정 패키지가 있는지 어떻게 알 수 있습니까? (0) | 2020.11.23 |