Java 给日期加1周,哪种方式更可取?

Java 给日期加1周,哪种方式更可取?,java,datetime,date,calendar,Java,Datetime,Date,Calendar,我正在查看一些工作中的代码,在代码如何处理当前时间增加1周的问题时遇到了不一致的情况,我想知道是否有任何理由认为一个代码比另一个更可取: 第一种是实用方法: public static Date addDaysToDate(final Date date, int noOfDays) { Date newDate = new Date(date.getTime()); GregorianCalendar calendar = new GregorianCalendar();

我正在查看一些工作中的代码,在代码如何处理当前时间增加1周的问题时遇到了不一致的情况,我想知道是否有任何理由认为一个代码比另一个更可取:

第一种是实用方法:

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;
}
第二个使用简单的毫秒算法:

long theFuture = System.currentTimeMillis() + (86400 * 7 * 1000);
Date nextWeek = new Date(theFuture);
第二种方法显然使用“幻数”来定义一周,但这可以移动到一个常数
millists\u IN_ONE_week=86400*7*1000
,因此除此之外,有什么理由认为这些方法中的一种比另一种更可取


基本上,我想改变代码,使其始终保持一致,但我不完全确定要删除哪一个。因此,任何一种方式的论证都是有用的。

越一般,它就越有用。
如果你总是加一周,我会选择第二种方法。如果您有不同的添加,我会选择第一个,如果需要,可能会将天替换为秒甚至毫秒。

第一个会更慢,因此如果性能有问题,第二个会更好。

首先,我认为您应该将其替换为JodaTime。这是一个非常好的时光图书馆。您需要查看此页面,以了解在特定时间点添加几天或几周是多么容易:无法做到这一点,具有不兼容JVM的移动设备。糟糕透了

您的第一个示例更易于阅读,也更易于开发人员使用。它还使用日历类,这是Java中普遍接受的处理日期的方法。使它更好的是,它有一个明确的方法名,可以为它所做的事情设定期望值


因此,如果您重构系统以一致地使用com.DaveJ.util.date.DateUtils.addDaysToDate(最终日期,int noOfDays),那么您可以在该方法中执行任何您想要的操作,无论是Calendar、millis还是Joda,并在应用程序中保持一致。别忘了为它编写一些单元测试

这要看情况了!由于闰秒、DST和其他日历的奇怪之处,这两者并不总是相等的

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


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

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


要使混淆完全,您还可以尝试添加(Calendar.WEEK OF the YEAR,1),但不确定这会有什么不同。

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

因为您在移动设备上使用它,所以第一种方法更可取。原因是您的代码应该独立于特定的日历、DST和其他问题,例如秒超限(闰秒)


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

对于前几天使用的第二种方法要非常小心。考虑

private static long ONE_YEAR_AS_MILLISECONDS = 365*24*60*60*1000;
这看起来很简单,但实际上不会产生预期的结果,因为乘法使用整数,当与其他整数相乘时,这些整数会导致数字溢出并产生意外结果。这是因为Java中的最大int值是2147483647,而一年中有31536000000毫秒。在我的机器上,上面的代码生成1471228928,这显然是不正确的

相反,您需要这样做:

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

可以在java 8、java 8 rocks中执行以下操作

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);
    }

有关仅限日期的值,请参见。这门课故意没有时间和时区

ZoneDateTime
对于日期时间值,用于表示日期和一天中的某个时间以及时区,以说明夏令时(DST)等异常情况

或者添加任意天数

ZonedDateTime later = now.plusDays( someNumberOfDays );
关于java.time 该框架内置于Java8及更高版本中。这些类取代了旧的麻烦的日期时间类,如
java.util.date
.Calendar
,&
java.text.SimpleDateFormat

该项目现已启动,建议迁移到java.time

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释

大部分java.time功能都在中向后移植到java 6和7,并进一步适应于中


该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场

咳嗽使用乔达时间<代码>日期时间newDate=date.plusWeeks(1)该代码使用主要基于Java 1.2的JVM在Windows Mobile设备上运行。Joda只针对1.4及更高版本进行了测试,所以我不想添加一个第三方库,它不是真正设计用于在我使用的平台上运行的。但是谢谢你的建议。它是在Windows Mobile设备上运行的,所以性能肯定是个问题。你认为它会(大致)产生多大的影响?取决于它被称为什么样的东西。要想有一个想法,你需要对它进行分析。不过,作为一个例子,在我必须查看的一些时间关键型代码中,我们不断地调用“new Date().getTime()”——将其替换为“System.currentTimeMillis()”,产生了显著的不同,因为我们没有重复实例化日期对象。“将会更慢”是非常主观的。日历和日期字段操作主要是关于更改基本的
long
表示形式
ZonedDateTime later = now.plusDays( someNumberOfDays );