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

Bob*_*Bob 13 java calendar date datepicker 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
Run Code Online (Sandbox Code Playgroud)

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

Bas*_*que 18

TL;博士

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

LocalDate.now(
    ZoneId.of( "Pacific/Auckland" ) 
)
.minusDays( 5 )
Run Code Online (Sandbox Code Playgroud)

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

Period.between( start , stop )
Run Code Online (Sandbox Code Playgroud)

解析

首先,您必须将字符串输入解析为日期时间对象.然后,您将使用这些对象执行业务逻辑.

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

在Java 8及更高版本中,使用java.time框架.请参阅教程.

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

那个时髦的双冒号语法是一个方法引用,一种说明其他代码应该调用什么方法的方法.

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

当前的日期

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

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate todayTunis = LocalDate.now( z ) ;
Run Code Online (Sandbox Code Playgroud)

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

减去日期

这在StackOveflow.com上已经多次得到解决.例如,如何使用Java日历从日期中减去X天?.有关详细信息,请参阅其他像这样的回答这一个我这一个我更多的细节.提示:"已过去"是一个关键搜索词.

简而言之,使用a Period来定义许多标准日,月和年.

LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();
Run Code Online (Sandbox Code Playgroud)

转储到控制台.

System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );
Run Code Online (Sandbox Code Playgroud)

localDate:2015-01-02至2015-01-09天:7

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


Men*_*ild 14

在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)
Run Code Online (Sandbox Code Playgroud)

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

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)
Run Code Online (Sandbox Code Playgroud)

使用类A令人满意的解决方案java.util.Date,GregorianCalendar等是很难找到的.您可以使用Tacktheritrix的答案,但必须注意这样一个事实,即计算的经过天数可能因子日部分而有所不同,java.util.Date并且由于忽略了日光节约开关(也就是时钟在世界许多地方跳了一个小时).

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