代码之家  ›  专栏  ›  技术社区  ›  DaveJohnston

给一个日期加上一周,哪种方式更好?

  •  25
  • DaveJohnston  · 技术社区  · 15 年前

    第一种是实用方法:

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

    MILLISECONDS_IN_ONE_WEEK = 86400 * 7 * 1000 除此之外,还有什么理由让这些方法中的一种比另一种更受欢迎呢?

    基本上,我想改变代码,使其始终保持一致,但我不完全确定要删除哪一个。所以任何这样或那样的论点都是有用的。

    10 回复  |  直到 15 年前
        1
  •  22
  •   Erick Robertson    15 年前

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

        2
  •  4
  •   PAA    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);
        }
    
        3
  •  3
  •   Community CDub    8 年前

    使用方法二要非常小心 caught me out

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

    这看起来很天真,但实际上不会产生预期的结果,因为乘法使用整数,当这些整数与其他整数相乘时,会导致数字溢出并产生意外的结果。这是因为Java中的最大int值是2147483647,而一年中有31536000000ms。在我的机器上,上面的代码产生1471228928,这显然是不正确的。

    private static long ONE_YEAR_AS_MILLISECONDS = 365L*24L*60L*60L*1000L;
    
        4
  •  1
  •   Freiheit    15 年前

    首先,我认为你应该用JodaTime来代替它。 http://joda-time.sourceforge.net/ 这是一个非常好的时光图书馆。您需要查看此页面,以了解向特定时间点添加天数或周有多容易: http://joda-time.sourceforge.net/key_period.html

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

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

        5
  •  0
  •   raven    15 年前

    越一般,就越有用。

        6
  •  0
  •   Rich    15 年前

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

        7
  •  0
  •   Po' Lazarus    15 年前

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

        8
  •  0
  •   Jörn Horstmann    15 年前

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

        9
  •  0
  •   Eugene Ryzhikov    15 年前

    GregorianCalendar 并使用 Calendar.getInstance()

        10
  •  0
  •   Community CDub    8 年前

    有关仅日期值,请参见 the Answer by javaHelper . 这个 LocalDate

    ZonedDateTime

    对于日期时间值,使用 ZonedDateTime 表示一天中的一个日期和时间以及一个时区,以说明诸如夏令时(DST)之类的异常情况。

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

    ZonedDateTime later = now.plusDays( someNumberOfDays );
    

    关于java.time

    这个 java.time 该框架内置于Java8及更高版本中。这些类取代了旧的麻烦的日期时间类,例如 java.util.Date .Calendar ,& java.text.SimpleDateFormat .

    这个 Joda-Time maintenance mode ,建议迁移到java.time。

    要了解更多信息,请参阅 Oracle Tutorial

    java.time的大部分功能都被移植到Java6&中;7英寸 ThreeTen-Backport Android 在里面 ThreeTenABP .

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