Java 将 1 周添加到日期,首选哪种方式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3300328/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:53:07  来源:igfitidea点击:

Add 1 Week to a Date, which way is preferred?

javadatetimedatecalendar

提问by DaveJohnston

I am reviewing some code at work and came across an inconsistency in how the code handles adding 1 week to the current time and was wondering if there was any reason why one should really be preferred over the other:

我正在工作中的一些代码,发现代码处理将当前时间增加 1 周的方式不一致,我想知道是否有任何理由为什么一个人应该比另一个人更受欢迎:

The first was a utility method:

第一个是实用方法:

public static Date addDaysToDate(final Date date, int noOfDays) {
    Date newDate = new Date(date.getTime());

    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(newDate);
    calendar.add(Calendar.DATE, noOfDays);
    newDate.setTime(calendar.getTime().getTime());

    return newDate;
}

And the second used simple millisecond arithmetic:

第二个使用简单的毫秒算法:

long theFuture = System.currentTimeMillis() + (86400 * 7 * 1000);
Date nextWeek = new Date(theFuture);

The second method obviously uses 'magic numbers' to define a week, but this could be moved to a constant MILLISECONDS_IN_ONE_WEEK = 86400 * 7 * 1000So other than that, is there any reasons why one of these methods should be preferred over the other?

第二种方法显然使用“幻数”来定义一周,但这可以移动到一个常量MILLISECONDS_IN_ONE_WEEK = 86400 * 7 * 1000所以除此之外,是否有任何理由为什么这些方法中的一种比另一种更受欢迎?

Basically I want to change the code to be consistent throughout, but I'm not entirely sure which one to remove. So any arguments one way or the other would be useful.

基本上我想将代码更改为始终一致,但我不完全确定要删除哪一个。因此,任何一种方式的争论都是有用的。

采纳答案by Erick Robertson

The two methods will behave differently on daylight savings boundaries. The first method will continue returning the same time of the day, regardless of daylight savings status. The second method will return times which vary an hour in each direction as daylight savings time starts and stops.

这两种方法在夏令时边界上的行为会有所不同。无论夏令时状态如何,第一种方法将继续返回当天的同一时间。第二种方法将返回随着夏令时开始和停止在每个方向上变化一小时的时间。

回答by raven

The more general, the more useful it will be. If you always add a week, I'd chose the second method. If you have different adds, I'd chose the first one, perhaps replacing days for seconds or even millis if needed.

越通用,就越有用。如果你总是增加一周,我会选择第二种方法。如果您有不同的添加,我会选择第一个,如果需要,可能会以秒或什至毫秒替换几天。

回答by Rich

The first will be slower, so if performance is an issue, the second one is better.

第一个会更慢,所以如果性能是一个问题,第二个会更好。

回答by Freiheit

First and foremost, I would argue that you replace it with JodaTime. http://joda-time.sourceforge.net/It is a very nice time library. You'll want to look at this page to see how easy it is to add days or weeks to a particular point in time: http://joda-time.sourceforge.net/key_period.htmlCan't do this, mobile device with incompatible JVM. Bummer.

首先,我认为你应该用 JodaTime 替换它。http://joda-time.sourceforge.net/这是一个非常好的时间库。您需要查看此页面以了解将天数或周数添加到特定时间点是多么容易:http: //joda-time.sourceforge.net/key_period.html不能这样做,移动设备与不兼容的 JVM。无赖。

Your first example is easier to read and will be easier to use by your developers. It also uses the Calendar classes which is the generally accepted way to manipulate dates in Java. What makes it better is that it has a clear method name that sets the expectation for what it does.

您的第一个示例更易于阅读,并且更易于您的开发人员使用。它还使用 Calendar 类,这是在 Java 中操作日期的普遍接受的方式。让它变得更好的是它有一个明确的方法名称,它设置了对它所做的事情的期望。

So if you refactor your system to consistently use com.DaveJ.util.date.DateUtils.addDaysToDate(final Date date, int noOfDays) you can then do whatever you want inside that method, be it Calendar or millis or Joda, and be consistent within your application. Don't forget to write some unit tests for it!

因此,如果您重构系统以始终使用 com.DaveJ.util.date.DateUtils.addDaysToDate(final Date date, int noOfDays),则可以在该方法中执行任何您想做的操作,无论是 Calendar 还是millis 或 Joda,并保持一致在您的应用程序中。不要忘记为它编写一些单元测试!

回答by Po' Lazarus

It depends! Because of leap seconds, DST and other calendar oddities, the two are not always equivalent.

这取决于!由于闰秒、夏令时和其他日历奇数,两者并不总是等价的。

For business and every day use, always use the first method and the performance are not bad at all. It will handle those things for you.

对于商务和日常使用,始终使用第一种方法,性能一点也不差。它会为你处理这些事情。

For scientific needs, often you have to use a monotone clock (here the second one).

出于科学需要,您通常必须使用单调时钟(这里是第二个)。

回答by J?rn Horstmann

The two methods might give different results when a change in daylight saving time is involved. Imagine the current time is 23:50 and at 02:00 the clock jumps to 03:00. When you just add 7 days in milliseconds the time would be 00:50 on the following day. Addings 7 days, the resulting time would still be 23:50.

当涉及夏令时的更改时,这两种方法可能会给出不同的结果。假设当前时间是 23:50,并且在 02:00 时钟跳到 03:00。当您以毫秒为单位添加 7 天时,时间将为第二天的 00:50。加上 7 天,结果时间仍然是 23:50。

To make the confusion complete, you could also try add(Calendar.WEEK_OF_YEAR, 1), not sure how that would differ though.

为了使混淆完整,您也可以尝试add(Calendar.WEEK_OF_YEAR, 1),但不确定这会有什么不同。

回答by Eugene Ryzhikov

Since you're using it on the mobile device, the first method is preferable. The reason is that your code should be independent of specific calendar, DST and other problems, such as seconds overrun(leap seconds).

由于您在移动设备上使用它,因此第一种方法更可取。原因是你的代码应该独立于特定的日历、夏令时等问题,比如秒溢出(leap seconds)。

You have to remove dependence on GregorianCalendarand create it using Calendar.getInstance().

您必须删除对的依赖GregorianCalendar并使用Calendar.getInstance().

回答by Chris Knight

Be very careful about using method two which caught me outthe other day. Consider

使用前几天让我失望的方法二时要非常小心。考虑

private static long ONE_YEAR_AS_MILLISECONDS = 365*24*60*60*1000;

This looks innocent enough, but in fact will not produce what is expected as the multiplication uses integers which, when multiplied by each the other integers, causes a numeric overflow and will yield an unexpected result. This is because the max int value in Java is 2,147,483,647 and yet there are 31,536,000,000 ms in a year. On my machine the above code produces 1,471,228,928 which is obviously not correct.

这看起来很无辜,但实际上不会产生预期的结果,因为乘法使用整数,当与其他整数相乘时,会导致数字溢出并产生意外结果。这是因为 Java 中的最大 int 值为 2,147,483,647,而一年有 31,536,000,000 毫秒。在我的机器上,上面的代码产生 1,471,228,928,这显然是不正确的。

Instead you need to do this:

相反,您需要这样做:

private static long ONE_YEAR_AS_MILLISECONDS = 365L*24L*60L*60L*1000L;

回答by Ash_P

The below can be done in java 8, Java 8 rocks!!

下面可以在java 8中完成,Java 8岩石

public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);

        //add 1 week to the current date
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        System.out.println("Next week: " + nextWeek);
    }

回答by Basil Bourque

For a date-only value, see the Answer by javaHelper. The LocalDateclass purposely has no time-of-day and no time zone.

对于仅限日期的值,请参阅javaHelper 的答案。该LocalDate班特意没有时间的天,没有时区。

ZonedDateTime

ZonedDateTime

For a date-time value, use ZonedDateTimeto represent a date and a time-of-day along with a time zone to account for anomalies such as Daylight Saving Time (DST).

对于日期时间值,使用ZonedDateTime来表示日期和时间以及时区,以说明夏令时 (DST) 等异常情况。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime weekLater = now.plusWeeks( 1 );

Or add some arbitrary number of days.

或者添加一些任意天数。

ZonedDateTime later = now.plusDays( someNumberOfDays );

About java.time

关于 java.time

The java.timeframework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了旧的麻烦的日期时间类,例如java.util.Date, .Calendar, & java.text.SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to java.time.

现在处于维护模式Joda-Time项目建议迁移到 java.time。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backportand further adapted to Androidin ThreeTenABP.

多的java.time功能后移植到Java 6和7在ThreeTen-反向移植并且还适于的AndroidThreeTenABP

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。