我想根据用户选择的持续时间添加月数。
我已经编写了以下代码,它采用当前日期并根据用户选择的持续时间添加月份,但我希望它采用从前端传递的开始日期并根据持续时间添加月份。
String le=ra.getLease_period(); //duration
String ls=ra.getLeasestart(); // start date
if (le.equals("1"))
{
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd" );
final Date dur1 = df.parse( ls ); // conversion from String
System.out.println("Start date passed is:" + dur1);
String m = df.format(dur1);
System.out.println("Formatted dur1 is" + m);
final java.util.Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime( date );
cal1.add(GregorianCalendar.MONTH, 1 ); // date manipulation
System.out.println("result:" + df.format( cal1.getTime() ) );
ra.setLeaseend(df.format( cal1.getTime() ));
}
您是否限于Java 7?使用Java 8s java.time软件包来做到这一点要好得多。
为什么将日期存储在字符串中?
joda.org/joda-time如果您不使用Java8,Joda Time是一个很棒的库。
当前输出是多少?什么是预期的输出?
@RealSkeptic,您可以在Java 7中使用java.time功能,这是我当然推荐的。请参见ThreeTen反向端口,即java.time到Java 6和7的反向端口。
而且Pra,无论您在Java 8或9中选择java.time,还是在Java 6或7中使用ThreeTen Backport,还是在Joda-Time中,我当然都建议您废弃过时的类SimpleDateFormat和Date。现代替代方案更易于使用,并且都为日期增加了几个月提供了更好的支持。
@Adriaan Koster当前输出是如果持续时间为1个月,则为当前日期加上1个月。预期的输出是,如果持续时间为1个月,则应在传递的"开始日期"中添加该1个月。.我在代码的注释中提到了开始日期。
如何在Java中将日期增加一天的可能重复项?
旧类(Date,Calendar和SimpleDateFormat)存在许多问题和设计问题,并且已被新的API取代。
如果您使用的是Java 8,请考虑使用新的java.time API。与旧的API相比,它更容易,更易于出错且更不易出错。
如果您使用的是Java <= 7,则可以使用ThreeTen Backport,这是Java 8的新日期/时间类的绝佳反向端口。对于Android,您还需要ThreeTenABP(更多有关如何在此处使用它的信息)。
下面的代码对两者都适用。
唯一的区别是包名称(在Java 8中为java.time,在ThreeTen Backport(或Android的ThreeTenABP)中为org.threeten.bp),但是类和方法的名称相同。
首先,您可以将输入String解析为LocalDate(使用DateTimeFormatter),然后使用方法plusMonths添加指定的月数。最后,使用相同的格式化程序格式化结果日期:
// assuming"le" and"ls" are as described in the question
if (le.equals("1")) {
// parse the input to a LocalDate
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate dt = LocalDate.parse(ls, fmt);
// add 1 month
LocalDate nextMonth = dt.plusMonths(Integer.parseInt(le));
// print it
System.out.println(fmt.format(nextMonth));
}
感谢大家的帮助。我通过在cal1.setTime()函数中传递开始日期解决了该问题。
Calendar cal1 = new GregorianCalendar();
cal1.setTime(ra.getLeasestart());
cal1.add(Calendar.MONTH, +1);
Date today1=cal1.getTime();
if(le.equals("1")){
System.out.println("Lease end date if duratio is 1:"+today1);
ra.setLeaseend(today1);
}
// and so one
感谢您发布解决方案。 我不禁要指出,您所犯的错误是现代日期和时间库之一所无法解决的。 所以重复我自己:摆脱SimpleDateFormat,Date和Calendar并开始使用不易出错的东西。
持续时间不应为日期。我会说这应该是一个整数(月数)。
final Integer dur1 = Integer.parseInt( le ); // conversion from String
final java.util.Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime( date );
cal1.add(GregorianCalendar.MONTH, dur1 ); // date manipulation
@StanislavL已经回答了这个问题...所以我只是提供这个来展示一些简单的探索性测试包装:
package time;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.Test;
public class TimeTest {
@Test
public void timeInputs1Month() throws ParseException {
Inputs ra = spy(new Inputs("2017-09-11","1"));
stackOverflowQuestion(ra);
verify(ra).setLeaseend(eq("2017-10-11"));
}
@Test
public void timeInputs12Months() throws ParseException {
Inputs ra = spy(new Inputs("2017-09-11","12"));
stackOverflowQuestion(ra);
verify(ra).setLeaseend(eq("2018-09-11"));
}
private void stackOverflowQuestion(Inputs ra) throws ParseException {
String le = ra.getLease_period(); //duration
String ls = ra.getLeasestart(); // start date
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
final Date date = df.parse(ls); // conversion from String
System.out.println("Start date passed is:" + date);
final java.util.Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime(date);
cal1.add(GregorianCalendar.MONTH, Integer.parseInt(le)); // date manipulation
ra.setLeaseend(df.format(cal1.getTime()));
}
private class Inputs {
private final String leaseStart;
private final String leasePeriod;
Inputs(String leaseStart, String leasePeriod) {
this.leaseStart = leaseStart;
this.leasePeriod = leasePeriod;
}
String getLease_period() {
return leasePeriod;
}
String getLeasestart() {
return leaseStart;
}
void setLeaseend(String leaseEnd) {
System.out.println("result:" + leaseEnd);
}
}
}
还值得注意的是SimpleDateFormat类不是线程安全的。