Java:减去日期的最简单方法

时间:2015-11-04 19:04:24

标签: java date datepicker calendar subtraction

我创建了一个包含两个字段的类,需要是日期start_datedate_passed。我一直在研究java中使用YYYY MM DD格式的日期的最佳方法,它允许简单的日期减法,以及“化妆”日期的能力,比如说将来。例如。

我希望它做的例子......

library.circulate_book("Chemistry", **start date here**) //actual date or random date
library.pass_book("Chemistry", **Date Passed here**) //random date such as 5 days after start date
int days_had = Date_Passed - start_date

到目前为止,我已经找到了很多方法来使用Calendars和Date类来格式化日期,但是还没有找到一个看起来像是在大多数日期最终成为字符串的方法。任何建议/小例子都非常感谢!此外,任何示例链接都很棒!

5 个答案:

答案 0 :(得分:14)

TL;博士

通过添加/减去天数从一个日期移动到另一个日期。

LocalDate.now(
    ZoneId.of( "Pacific/Auckland" ) 
)
.minusDays( 5 )

计算两个日期之间经过的天数,月数和年数。

Period.between( start , stop )

解析

首先,您必须将字符串输入解析为日期时间对象。然后,您将使用这些对象预先形成business logic

不要将日期时间值视为字符串,这会让你疯狂。我们在代码中使用日期时间对象;我们使用该日期时间对象的字符串表示与用户或其他应用程序交换数据。

在Java 8及更高版本中,使用java.time框架。见Tutorial

您只想要一个日期,没有时间,所以我们可以使用LocalDate类。

这个时髦的双冒号语法是method reference,这是一种说明其他代码应该调用哪种方法的方法。

String input = "2015 01 02";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" );
LocalDate localDate = formatter.parse ( input , LocalDate :: from );

当前日期

确定今天的日期需要一个时区。对于任何给定的时刻,日期在全球范围内因地区而异。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate todayTunis = LocalDate.now( z ) ;

如果您想要JVM的当前默认时区,请致电ZoneId.systemDefault

减去日期

之前在StackOveflow.com上已经多次解决了这个问题。例如,How to subtract X days from a date using Java calendar?。有关详细信息,请参阅其他答案,例如this one by methis one by me以获取更多详细信息。提示:"已过去"是一个关键的搜索词。

简而言之,使用Period来定义标准天数,月数和年数。

LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();

转储到控制台。

System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );
  

localDate:2015-01-02至2015-01-09 in days:7

请注意Period仅适用于整天的限制,即没有时间的仅限日期的值。这就是我们在这个问题上所需要的,所以完成了工作。如果您有日期时间值(ZonedDateTime个对象),请使用上面链接的问题/答案中提到的ThreeTen-Extra项目的Days类。

答案 1 :(得分:8)

在Java-8中做到这一点的最好方法不是Basil Bourque的错误答案,而是这种方法:

String startDate = "2016 01 02";
String passedDate = "2016 02 29";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate date1 = LocalDate.parse(startDate, formatter);
LocalDate date2 = LocalDate.parse(passedDate, formatter);

long elapsedDays = ChronoUnit.DAYS.between(date1, date2);
System.out.println(elapsedDays); // 58 (correct)

建议使用java.time.Period.getDays()是危险的,并且一旦持续时间超过一个月,通常就会出错。整个Period是P1M27D所以这段代码实际上只查询部分已用天数(还有一个已过去的月份):

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)

很难找到使用类java.util.DateGregorianCalendar等的令人满意的解决方案。您可以使用Tacktheritrix的答案,但必须注意以下事实:计算的经过天数可能会因java.util.Date的子日部分而有所不同,因为忽略了日光节约开关(世界上许多地方的时钟跳跃一小时)也不可靠)。

附注:至少 8个外部库也能为您的问题提供良好的答案。但我认为,除非你尚未使用Java-8,否则你的简单用例并不能证明嵌入额外的库是正确的。任何替代解决方案如何计算两个日期之间的经过天数并不比Java-8更容易 - 只是类似。既然你接受了Basil Bourque的Java-8相关答案,我认为你确实在Java-8上,所以我忽略了如何解决你的其他库的问题。

答案 2 :(得分:2)

使用java 8 date api或joda,不需要新的发明。

您可以在此处找到一些示例:http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/

答案 3 :(得分:1)

以下是使用Calendar的答案:

Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();

cal2.setTime(cal.getTime());
cal2.add(Calendar.DAY_OF_YEAR, 5);
System.out.println((cal2.getTimeInMillis() - cal.getTimeInMillis()) / (1000d * 60 * 60 * 24));

答案 4 :(得分:0)

如果你对旧的Java感到困惑,你可以使用SimpleDateFormat。

    //For substraction
    long differenceInMillis = date1.getTime() - date2.getTime();

    //Date Format
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd");
    String dateAsString = dateFormat.format(date1); //To get a text representation
    Date dateParsed = dateFormat.parse(dateAsString); //To get it back as date