在我的脚本中,我需要在给定开始日期和结束日期的日期范围内执行一组操作。
请为我提供使用Java实现此目的的指导。
for ( currentDate = starDate; currentDate < endDate; currentDate++) {
}
我知道上面的代码根本是不可能的,但是我这样做是为了向您展示我想要实现的目标。
在我的脚本中,我需要在给定开始日期和结束日期的日期范围内执行一组操作。
请为我提供使用Java实现此目的的指导。
for ( currentDate = starDate; currentDate < endDate; currentDate++) {
}
我知道上面的代码根本是不可能的,但是我这样做是为了向您展示我想要实现的目标。
Answers:
好吧,您可以使用Java 8的time-API专门针对此问题java.time.LocalDate
(或与Java 7及更早版本等效的Joda Time类)执行类似的操作
for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
...
}
我会彻底建议java.time
在内置Date
/ Calendar
类上使用(或Joda Time)。
import
语句即可。
JodaTime很不错,但是,为了完整性和/或(如果您更喜欢API提供的功能),以下是标准的API方法。
从java.util.Date
下面的实例开始时:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");
java.util.Calendar
如果您尚未使用Java8,以下是传统方法:
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);
for (Date date = start.getTime(); start.before(end); start.add(Calendar.DATE, 1), date = start.getTime()) {
// Do your job here with `date`.
System.out.println(date);
}
这是Java8的java.time.LocalDate
方法,基本上就是JodaTime方法:
LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) {
// Do your job here with `date`.
System.out.println(date);
}
如果您想重复包含结束日期,请分别使用!start.after(end)
和!date.isAfter(end)
。
Java 8样式,使用java.time类:
// Monday, February 29 is a leap day in 2016 (otherwise, February only has 28 days)
LocalDate start = LocalDate.parse("2016-02-28"),
end = LocalDate.parse("2016-03-02");
// 4 days between (end is inclusive in this example)
Stream.iterate(start, date -> date.plusDays(1))
.limit(ChronoUnit.DAYS.between(start, end) + 1)
.forEach(System.out::println);
输出:
2016-02-28
2016-02-29
2016-03-01
2016-03-02
选择:
LocalDate next = start.minusDays(1);
while ((next = next.plusDays(1)).isBefore(end.plusDays(1))) {
System.out.println(next);
}
Java 9添加了dateUntil()方法:
start.datesUntil(end.plusDays(1)).forEach(System.out::println);
这基本上与BalusC给出的答案相同,但是用while循环代替for循环更具可读性:
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);
while( !start.after(end)){
Date targetDay = start.getTime();
// Do Work Here
start.add(Calendar.DATE, 1);
}
Apache Commons
for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
// ...
}
addDays(..)
,它就会变得更短。
private static void iterateBetweenDates(Date startDate, Date endDate) {
Calendar startCalender = Calendar.getInstance();
startCalender.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
for(; startCalender.compareTo(endCalendar)<=0;
startCalender.add(Calendar.DATE, 1)) {
// write your main logic here
}
}
我们可以将逻辑迁移到Java 7,Java 8和Java 9的各种方法中:
public static List<Date> getDatesRangeJava7(Date startDate, Date endDate) {
List<Date> datesInRange = new ArrayList<>();
Calendar startCalendar = new GregorianCalendar();
startCalendar.setTime(startDate);
Calendar endCalendar = new GregorianCalendar();
endCalendar.setTime(endDate);
while (startCalendar.before(endCalendar)) {
Date result = startCalendar.getTime();
datesInRange.add(result);
startCalendar.add(Calendar.DATE, 1);
}
return datesInRange;
}
public static List<LocalDate> getDatesRangeJava8(LocalDate startDate, LocalDate endDate) {
int numOfDays = (int) ChronoUnit.DAYS.between(startDate, endDate);
return IntStream.range(0, numOfDays)
.mapToObj(startDate::plusDays)
.collect(Collectors.toList());
}
public static List<LocalDate> getDatesRangeJava9(LocalDate startDate, LocalDate endDate) {
return startDate.datesUntil(endDate).collect(Collectors.toList());
}
然后,我们可以按以下方式调用这些方法:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");
List<Date> dateRangeList = getDatesRangeJava7(startDate, endDate);
System.out.println(dateRangeList);
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
List<LocalDate> dateRangeList8 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList8);
List<LocalDate> dateRangeList9 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList9);
输出为:
[2010年12月20日星期一IST 2010,12月21日星期二00:00:00 IST 2010,12月22日星期三00:00:00 IST 2010,12月23日星期四00:00:00 IST 2010,星期五12月24日00: IST 2010,00:00 IST,12月25日星期六00:00:00,IST 2010]
[2010-12-20、2010-12-21、2010-12-22、2010-12-23、2010-12-24、2010-12-25]
[2010-12-20、2010-12-21、2010-12-22、2010-12-23、2010-12-24、2010-12-25]
Date
和Calendar
类被java.time类所取代。具体来说,由Instant
和代替ZonedDateDate
。
这是Java 8代码。我认为这段代码将解决您的问题。快乐编码
LocalDate start = LocalDate.now();
LocalDate end = LocalDate.of(2016, 9, 1);//JAVA 9 release date
Long duration = start.until(end, ChronoUnit.DAYS);
System.out.println(duration);
// Do Any stuff Here there after
IntStream.iterate(0, i -> i + 1)
.limit(duration)
.forEach((i) -> {});
//old way of iteration
for (int i = 0; i < duration; i++)
System.out.print("" + i);// Do Any stuff Here
为什么不使用纪元并轻松遍历。
long startDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(startDate).getTime() / 1000;
long endDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(endDate).getTime() / 1000;
long i;
for(i=startDateEpoch ; i<=endDateEpoch; i+=86400){
System.out.println(i);
}
您可以编写一个类似的类(实现迭代器接口)并对其进行迭代。
public class DateIterator implements Iterator<Date>, Iterable<Date>
{
private Calendar end = Calendar.getInstance();
private Calendar current = Calendar.getInstance();
public DateIterator(Date start, Date end)
{
this.end.setTime(end);
this.end.add(Calendar.DATE, -1);
this.current.setTime(start);
this.current.add(Calendar.DATE, -1);
}
@Override
public boolean hasNext()
{
return !current.after(end);
}
@Override
public Date next()
{
current.add(Calendar.DATE, 1);
return current.getTime();
}
@Override
public void remove()
{
throw new UnsupportedOperationException(
"Cannot remove");
}
@Override
public Iterator<Date> iterator()
{
return this;
}
}
并像这样使用它:
Iterator<Date> dateIterator = new DateIterator(startDate, endDate);
while(dateIterator.hasNext()){
Date selectedDate = dateIterator .next();
}
您可以尝试以下方法:
OffsetDateTime currentDateTime = OffsetDateTime.now();
for (OffsetDateTime date = currentDateTime; date.isAfter(currentDateTime.minusYears(YEARS)); date = date.minusWeeks(1))
{
...
}
这将帮助您从30天开始,一直循环到今天。您可以轻松更改日期范围和方向。
private void iterateThroughDates() throws Exception {
Calendar start = Calendar.getInstance();
start.add(Calendar.DATE, -30);
Calendar end = Calendar.getInstance();
for (Calendar date = start; date.before(end); date.add(Calendar.DATE, 1))
{
System.out.println(date.getTime());
}
}