我正在尝试获取一系列日期,而我的输入是'from'/'to'结构。 所以我的意见是:
String date1 = "2014-01-01";
String date2 = "2014-05-01";
我的输出应该是一个Arraylist,其中所有日期都在date1和date2之间。 我已经找到了这个,但我只能找到关于两个日期之间差异的问题:
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
try {
Date date1 = myFormat.parse(inputString1);
Date date2 = myFormat.parse(inputString2);
long diff = date2.getTime() - date1.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff,TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}
任何提示或建议?所有其他问题都适用于iOS或SQL。
答案 0 :(得分:4)
看看JodaTime:http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html
DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);
List<Date> allDates = new ArrayList();
while( dateTime1.before(dateTime2) ){
allDates.add( dateTime1.toDate() );
dateTime1 = dateTime1.plusDays(1);
}
答案 1 :(得分:1)
如果您不想使用第三方库,可以使用Calendar
:
public static void main(String[] args) throws Exception {
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
ArrayList<Date> dates = new ArrayList<Date>();
try {
Date date1 = myFormat.parse(inputString1);
Calendar c1 = DateToCalendar(date1);
Date date2 = myFormat.parse(inputString2);
Calendar c2 = DateToCalendar(date2);
while (!areEqualDate(c1, c2)) {
dates.add(c1.getTime());
System.out.println (c1.getTime());
c1.add(Calendar.DAY_OF_YEAR, 1);
}
} catch (ParseException e) {
e.printStackTrace();
}
// ArrayList<Date> dates >> contain all dates between both given days.
}
private static boolean areEqualDate(Calendar c1, Calendar c2) {
if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) return false;
if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) return false;
if (c1.get(Calendar.DAY_OF_YEAR) != c2.get(Calendar.DAY_OF_YEAR)) return false;
return true;
}
public static Calendar DateToCalendar(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
答案 2 :(得分:1)
我喜欢JodaTime,但是使用java.util.Calendar
也可以在没有第三方库的情况下完成。给定一个Calendar
对象,可以使用其add
方法来增加日期的某些字段,同时遵守日历规则(比如在1月31日添加1天会让您到2月1日,而不是到1月32日)。
首先按照正确的时间顺序将日期分别放入一个Calendar
个对象中,以便稍后添加正确的方向:
Calendar cStart = Calendar.getInstance(),
cStop = Calendar.getInstance();
if (date1.before(date2)) {
cStart.setTime(date1);
cStop.setTime(date2);
} else {
cStart.setTime(date2);
cStop.setTime(date1);
date1
和date2
是您问题中已解析的Date
个对象,为简单起见。
接下来,循环播放&#34;将1添加到每年的日期&#34;指示直到超过停止日期:
do {
System.out.println(pretty(cStart));
cStart.add(Calendar.DAY_OF_YEAR, 1);
} while (cStart.before(cStop));
最后打印停止日期
System.out.println(pretty(cStop));
pretty()
只是通过SDF发送日历的一些迷你方法,就像你首先用来解析字符串一样。
此解决方案将打印日期范围,包括开始日期和停止日期,并且可能需要围绕边缘情况进行一些调整(如date1==date2
)。可以轻松调整以排除开始和停止日期。当然可以交换打印以进行聚合。要从日历中获取Date对象,请使用getTime()
方法(返回快照,而不是实时参考)。
可以找到相关(Gregorian)Calendar
的文档here。
答案 3 :(得分:1)
以下是两个字符串日期之间获取日期数组的代码。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
public class DateFormatExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String date1 = "2014-01-01";
String date2 = "2014-05-01";
try {
Date d1 = myFormat.parse(date1);
Date d2 = myFormat.parse(date2);
List<Date> allDates = new ArrayList<Date>();
List<String> allDatesString = new ArrayList<String>();
while( d1.before(d2) ){
d1 = addDays(d1, 1);
allDates.add(d1);
allDatesString.add(formatter.format(d1));
}
System.out.println(allDates);
System.out.println(allDatesString);
} catch (ParseException e) {
e.printStackTrace();
}
}
private static Date addDays(Date d1, int i) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d1);
cal.add(Calendar.DATE, 1);
return cal.getTime();
}
}
答案 4 :(得分:0)
我已经知道OP不使用Java 8,但这是当前的解决方案 - Java已经过改进,新的java.time
API可以完成这方面的所有工作:
//change these values :
LocalDate ld1 = LocalDate.ofEpochDay(0);
LocalDate ld2 = LocalDate.now();
//do NOT change these:
final LocalDate begin = ld1.isBefore(ld2) ? ld1 : ld2;
final LocalDate end = ld2.isAfter(ld1) ? ld2 : ld1;
for (int i = 0; i < begin.until(end, ChronoUnit.DAYS); i++) {
final LocalDate curDate = begin.plusDays(i);
System.out.println("current date : " + curDate);
}
这将在两个日期之间输出每个有效日,而大多数其他解决方案也会为您提供无效的日;事实上:时间计算需要在与时区无关的数据上进行 - 另一方面,输出很可能是时区和/或时间顺序依赖的。
这就是为什么有像java.time.format
这样的软件包 - 只需计算您所选区域的时间/日期值和格式 ...就是如何正确完成它们。
如果您需要转换时态输入,那么time-API中也有一些有用的功能,我建议您对该主题进行全面的教程,一些好的介绍可能是this,尤其是that:
表示时间有两种基本方法。一种方式代表时间 人类术语,称为人类时间,如年,月,日, 小时,分钟和秒。另一方面,机器时间,测量时间 连续沿着一个来自原点的时间线,称为时代,在 纳秒分辨率。 Date-Time包提供了丰富的数组 用于表示日期和时间的类。日期时间中的某些类 API旨在表示机器时间,而其他API则更适合 代表人类的时间。
答案 5 :(得分:0)
如果你使用的是番石榴,那么这个问题有一个非常优雅的解决方案。
Guava有两个简洁的类,例如Range和ContiguousSet,它们实现了你所需要的:第一个操作值范围,第二个操作 - 能够将范围转换为一组离散值。
两者的使用示例(与JodaTime一起):
LocalDate start = LocalDate.parse("2015-01-01");
LocalDate end = LocalDate.parse("2019-02-01");
Range<LocalDate> range = Range.closed(start, end); //Creates a "closed" range, that is both dates are inclusive. There are also options like "openClosed", "closedOpen" and "open"
final Set<LocalDate> daySet = ContiguousSet.create(range, LocalDateDomain.INSTANCE); //Create a "virtual" set of days in given the range. "virtual" part means that if you create a set of 10 thousand years, it will not eat your memory at all
for (LocalDate day : daySet) {
//...operation...
}
就个人而言,我真的更喜欢这种方式,因为它消除了理解封闭/开放范围的一些问题,并使代码更容易阅读和理解,同时不会影响性能。此外,它适用于任何类型的日期,任何库(您可以将YodaTime交换为Java8日期甚至Java7-基于日期的实现)。
此外,它允许你在交叉点,联合,范围跨度,令人难以置信的快速“包含”等范围内进行一些巧妙的操作。
唯一的缺点是:
LocalDateDomain实现示例,它作为Guava和JodaTime之间的桥梁运行:
public class LocalDateDomain extends DiscreteDomain<LocalDate> {
public static final LocalDateDomain INSTANCE = new LocalDateDomain();
@Override
public LocalDate next(LocalDate value) {
return value.plusDays(1);
}
@Override
public LocalDate previous(LocalDate value) {
return value.minusDays(1);
}
@Override
public long distance(LocalDate start, LocalDate end) {
return Days.daysBetween(start, end).getDays();
}
}