我有两个日期:
Start Date: 2017-01-15
End Date: 2017-05-27
现在我想找到这两个日期之间的整个月份。所以结果应该是:
Feb-2017
Mar-2017
Apr-2017
1月未包含在结果中,因为开始日期从月中开始,并且不包括5月,因为结束日期不包括整个5月份。
如何使用Java实现这一目标?
我尝试过这样的事情:
String date1 = "2015-01-15";
String date2 = "2015-05-27";
DateFormat formater1 = new SimpleDateFormat("MMM-yyyy");
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
Calendar startCalendar = Calendar.getInstance();
Calendar endCalendar = Calendar.getInstance();
try {
startCalendar.setTime(formater.parse(date1));
endCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("startDate:" + startCalendar.getTime());
System.out.println("endCalendar:" + endCalendar.getTime());
while (startCalendar.before(endCalendar)) {
// add one month to date per loop
String date = formater1.format(startCalendar.getTime()).toUpperCase();
System.out.println(date);
startCalendar.add(Calendar.MONTH, 1);
}
但我不知道如何从结果中排除Jan和May。目前,我得到了这个结果:
JAN-2015
FEB-2015
MAR-2015
APR-2015
MAY-2015
答案 0 :(得分:3)
随着Java 8的发布,Oracle大大改进了日期时间库,使实现日历逻辑变得更加简单。有关详细信息,请查看java.time文档。支持的功能包括withDayOfMonth
和lastDayOfMonth
,可让您查找给定月份内的特定日期。
使用java.time API进行格式化和日期操作,看看这个实现:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM-yyyy");
LocalDate start = LocalDate.of(2017, 1, 15);
LocalDate end = LocalDate.of(2017, 5, 27);
List<String> months = new ArrayList<>();
LocalDate date = start;
if (date.getDayOfMonth() == 1) {
date = date.minusDays(1);
}
while (date.isBefore(end)) {
if (date.plusMonths(1).with(lastDayOfMonth()).isAfter(end)) {
break;
}
date = date.plusMonths(1).withDayOfMonth(1);
months.add(date.format(formatter).toUpperCase());
}
System.out.println(months);
}
}
输出:
> [FEB-2017, MAR-2017, APR-2017]
答案 1 :(得分:1)
我能够通过以下代码解决这个问题:
public static void main(String... strings) throws ParseException {
String date1 = "2017-01-01";
String date2 = "2017-05-27";
DateFormat formater1 = new SimpleDateFormat("MMM-yyyy");
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
Calendar startCalendar = Calendar.getInstance();
Calendar endCalendar = Calendar.getInstance();
try {
startCalendar.setTime(formater.parse(date1));
endCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
e.printStackTrace();
}
while (startCalendar.before(endCalendar)) {
if (isFirstDayofMonth(startCalendar) && !(startCalendar.get(Calendar.MONTH) == endCalendar.get(Calendar.MONTH) && startCalendar.get(Calendar.YEAR) == endCalendar.get(Calendar.YEAR))) {
String date = formater1.format(startCalendar.getTime()).toUpperCase();
System.out.println(date);
}
startCalendar.set(Calendar.DATE, 1);
startCalendar.add(Calendar.MONTH, 1);
}
if (isLastDayofMonth(endCalendar)) {
String date = formater1.format(endCalendar.getTime()).toUpperCase();
System.out.println(date);
}
}
private static boolean isFirstDayofMonth(Calendar calendar) {
if (calendar == null) {
return false;
}
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
return (dayOfMonth == 1);
}
private static boolean isLastDayofMonth(Calendar calendar) {
if (calendar == null) {
return false;
}
boolean isLastDay = calendar.get(Calendar.DATE) == calendar.getActualMaximum(Calendar.DATE);
return isLastDay;
}
答案 2 :(得分:0)
我编写了一个不使用Months和Date格式化程序的程序,我正在手动处理所有格式。
public class cn {
public enum Months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}
public static void main(String arg[]) {
String s = "2015-01-15";
String e = "2016-05-27";
String s1[] = s.split("-");
String e1[] = e.split("-");
int syear = Integer.parseInt(s1[0]);
int smonth = Integer.parseInt(s1[1]);
int sday = Integer.parseInt(s1[2]);
int fyear = Integer.parseInt(e1[0]);
int fmonth = Integer.parseInt(e1[1]);
int fday = Integer.parseInt(e1[0]);
if (syear == fyear) {
for (int i = smonth + 1; i < fmonth; i++) {
System.out.println(Months.values()[i] + "-" + syear);
}
} else {
int i = 0;
while (syear <= fyear) {
if (syear < fyear) {
for (i = smonth + 1; i < 12; i++) {
System.out.println(Months.values()[i] + "-" + syear);
}
i = 1;
syear++;
} else {
for (; i < fmonth; i++) {
System.out.println(Months.values()[i] + "-" + syear);
}
}
}
}
}
}
修改强>
以上课程也适用于不同年份。
答案 3 :(得分:0)
YearMonth.from(
LocalDate.parse( "2017-01-15" )
)
.plusMonths( 1 )
.format( DateTimeFormatter.ofPattern( "MMM-uuuu" , Locale.US ) )
FEB-2017
YearMonth
Answer by nbrooks很好。或者,我们可以使用代表一年中的YearMonth
类。
LocalDate startDate = LocalDate.parse( "2017-01-15" ) ;
LocalDate stopDate = LocalDate.parse( "2017-05-27" ) ;
获取每个YearMonth
。
YearMonth start = YearMonth.from( startDate ) ;
YearMonth stop = YearMonth.from( stopDate ) ;
收集中间人。
int initialCapacity = ( (int) ChronoUnit.MONTHS.between( startDate , stopDate ) ) + 1 ; // Adding one for good measure - I didn't really think out this detail.
List< YearMonth > yms = new ArrayList<>( initialCapacity ) ;
循环每个增量月份。
YearMonth ym = start.plusMonths( 1 ) ; // Add one, to *not* include the first month.
while ( ym.isBefore( stop ) ) { // Do *not* include the last month.
yms.add( ym ) ;
ym = ym.plusMonths( 1 ) ;
}
转储到控制台。
System.out.println("Months between " + startDate + " and " + stopDate + " = " + yms ) ;
请参阅此code run live at IdeOne.com。
2017-01-15和2017-05-27之间的月份= [2017-02,2017-03,2017-04]
以您希望显示YearMonth
值的任何格式生成字符串。默认值为标准ISO 8601格式。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM-uuuu" , Locale.US ) ;
for( YearMonth yearMonth : yms ) {
System.out.println( yearMonth.format( f ) ) ;
}
FEB-2017
MAR-2017
APR-2017
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。