Java:减去日期的最简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33530011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: Easiest Way to Subtract Dates
提问by Bob
I have created a class with two fields that need to be dates, start_date
and date_passed
. I have been researching the best way in java to have dates in a YYYY MM DD
format that allows for easy date subtraction, and the ability to "make-up" a date, say in the future for example.
我创建了一个包含两个字段的类,这些字段需要是日期start_date
和date_passed
. 我一直在研究 Java 中日期YYYY MM DD
格式的最佳方法,该格式允许简单的日期减法,以及“组成”日期的能力,例如在未来。
Example of what I'd like it to do...
我希望它做什么的例子......
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
So far, I've found plenty of ways to format dates using Calendars and Date classes, but have yet to find one that looks like it would work considering most dates end up as Strings. Any suggestions/small examples are greatly appreciated! Also, any links to examples would be awesome!
到目前为止,我已经找到了很多使用 Calendars 和 Date 类来格式化日期的方法,但还没有找到一种看起来像考虑到大多数日期最终都是字符串的方法。非常感谢任何建议/小例子!此外,任何指向示例的链接都很棒!
采纳答案by Basil Bourque
tl;dr
tl;博士
To move from one date to another by adding/subtracting a number of days.
通过添加/减去天数从一个日期移动到另一个日期。
LocalDate.now(
ZoneId.of( "Pacific/Auckland" )
)
.minusDays( 5 )
To calculate the number of days, months, and years elapsed between two dates.
计算两个日期之间经过的天数、月数和年数。
Period.between( start , stop )
Parsing
解析
First you must parse your string inputs into date-time objects. Then you work on preforming your business logicwith those objects.
首先,您必须将字符串输入解析为日期时间对象。然后,您可以使用这些对象来执行您的业务逻辑。
Stop thinking of date-time values as strings, that will drive you nuts. We work with date-time objects in our code; we exchange data with users or other apps using a String representation of that date-time object.
不要将日期时间值视为字符串,这会让您发疯。我们在代码中使用日期时间对象;我们使用该日期时间对象的字符串表示与用户或其他应用程序交换数据。
In Java 8 and later, use the java.timeframework. See Tutorial.
在 Java 8 及更高版本中,使用java.time框架。请参阅教程。
You want only a date, without time-of-day, so we can use the LocalDate
class.
你只想要一个日期,没有时间,所以我们可以使用这个LocalDate
类。
That funky double-colon syntax is a method reference, a way to say what method should be called by other code.
那个时髦的双冒号语法是方法引用,一种说明其他代码应该调用什么方法的方法。
String input = "2015 01 02";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" );
LocalDate localDate = formatter.parse ( input , LocalDate :: from );
Current date
当前的日期
Determining today's date requires a time zone. For any given moment, the date varies around the globe by zone.
确定今天的日期需要一个时区。对于任何给定时刻,日期因地区而异。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate todayTunis = LocalDate.now( z ) ;
If you want the JVM's current default time zone, call ZoneId.systemDefault
.
如果您想要 JVM 的当前默认时区,请调用ZoneId.systemDefault
.
Subtracting Dates
减去日期
This has been addressed many times before on StackOveflow.com. For example, How to subtract X days from a date using Java calendar?. For details, see other Answers such as this one by meand this one by mefor more details. Tip: "elapsed" is a key search word.
之前在 StackOveflow.com 上已经多次解决这个问题。例如,如何使用 Java 日历从日期中减去 X 天?. 有关详细信息,请参阅其他答案,例如我的这个答案和我的这个答案以获取更多详细信息。提示:“经过”是一个关键的搜索词。
Briefly, use a Period
to define a number of standard days, months, and years.
简而言之,使用 aPeriod
来定义一些标准的天数、月数和年数。
LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();
Dump to console.
转储到控制台。
System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );
localDate: 2015-01-02 to 2015-01-09 in days: 7
localDate:2015-01-02 到 2015-01-09 天数:7
Note the limitation that Period
works only with whole days, that is, date-only values without time-of-day. That is what we need here for this Question, so job done. If you had date-time values (ZonedDateTime
objects), use the ThreeTen-Extraproject's Days
class as noted in linked Question/Answer above.
请注意Period
仅适用于整日的限制,即没有时间的仅日期值。这就是我们在这个问题上所需要的,所以工作完成了。如果您有日期时间值(ZonedDateTime
对象),请使用上面链接的问题/答案中所述的ThreeTen-Extra项目的Days
类。
回答by Emerson Cod
use java 8 date api or joda, no need for new inventions.
使用 java 8 date api 或 joda,无需新发明。
you can find some examples here: http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/
你可以在这里找到一些例子:http: //examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/
回答by liloargana
If you are stuck withan older java you can use SimpleDateFormat.
如果您坚持使用较旧的 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
回答by Evan LaHurd
Here's an answer using Calendar
:
这是使用的答案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));
回答by Meno Hochschild
The best way to do this in Java-8 is not the flawed answer of Basil Bourque but this approach:
在 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)
The suggested use of java.time.Period.getDays()
is dangerous and often wrong as soon as the elapsed duration exceeds one month. The whole Period
is P1M27D so this code effectively only queries the partial amount of elapsed days (there is also an elapsed month):
java.time.Period.getDays()
一旦经过的持续时间超过一个月,建议的使用是危险的并且经常是错误的。整体Period
是 P1M27D 所以这段代码有效地只查询部分经过的天数(还有一个经过的月份):
System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)
A satisfying solution using the classes java.util.Date
, GregorianCalendar
etc. is hard to find.You can use the answer of Tacktheritrix but have to be aware of the fact that the calculated count of elapsed days might differ due to the sub-day-parts of java.util.Date
and is also not reliable because of ignoring day-light-saving switches (where the clock jumps by one hour in many parts of the world).
一个令人满意的解决方案使用的类java.util.Date
,GregorianCalendar
等是很难找到的。您可以使用 Tacktheritrix 的答案,但必须注意这样一个事实,即计算的经过天数可能会因子日部分而有所不同,java.util.Date
并且由于忽略夏令时开关(其中在世界许多地方,时钟会跳一小时)。
Side note: At least 8 external librariesoffer good answers to your problem, too. But I think, your simple use-case does not justify the embedding of an extra library unless you are not yet on Java-8. Any alternative solution how to count the elapsed days between two dates would not be easier than in Java-8 - only similar. And since you accepted the Java-8-related answer of Basil Bourque, I assume that you are indeed on Java-8 so I leave out the answer how to solve your problem with other libraries.
旁注:至少有8 个外部库也为您的问题提供了很好的答案。但我认为,除非您还没有使用 Java-8,否则您的简单用例并不能证明嵌入额外的库是合理的。任何如何计算两个日期之间经过的天数的替代解决方案都不会比 Java-8 更容易——只是相似。并且由于您接受了 Basil Bourque 与 Java-8 相关的答案,因此我假设您确实在使用 Java-8,因此我省略了如何使用其他库解决您的问题的答案。