在Java中为日期添加n小时?


136

如何将n小时添加到Date对象?我在StackOverflow上找到了另一个使用天数的示例,但仍然不知道如何使用数小时。



3
如果可能,请使用Java 8日期和时间。
pepseps

@Babar FYI,Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。请参见Oracle教程
罗勒·布尔克

Answers:


210

检查日历类。它具有add允许时间操纵的方法(和其他一些方法)。这样的事情应该起作用。

    Calendar cal = Calendar.getInstance(); // creates calendar
    cal.setTime(new Date()); // sets calendar time/date
    cal.add(Calendar.HOUR_OF_DAY, 1); // adds one hour
    cal.getTime(); // returns new date object, one hour in the future

检查API以获取更多信息。


4
如果要处理夏时制/夏令时,请小心。
CurtainDog 2010年

5
不用说您可以添加“负数小时”
pramodc84

6
@CurtainDog Using Calendar.add()会自动处理该问题。
Jesper 2010年

6
不需要cal.setTime(new Date())-Calendar.getInstance()的javadoc说:“返回的日历基于默认时区中具有默认语言环境的当前时间。”
mithrandir 2014年

仅供参考,麻烦的旧日期,时间类,如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在的遗产,由取代java.time内置到Java 8的Java 9.请参见类教程由Oracle
罗勒·布尔克

82

如果使用Apache Commons / Lang,则可以使用DateUtils.addHours()以下步骤一步一步完成:

Date newDate = DateUtils.addHours(oldDate, 3);

(原始对象未更改)


3
您还可以使用negativ小时:DateUtils.addHours(oldDate, -1);
Kaptain

在幕后,这确实与Nikita的答案一样,但这非常简单且易于阅读。另外,如果您已经使用过Apache Commons / Lang ...为什么不呢?
马特

28

为了简化@Christopher的示例。

说你有一个常数

public static final long HOUR = 3600*1000; // in milli-seconds.

你可以写。

Date newDate = new Date(oldDate.getTime() + 2 * HOUR);

如果使用long代替日期对象来存储日期/时间,则可以执行

long newDate = oldDate + 2 * HOUR;

26

tl; dr

myJavaUtilDate.toInstant()
              .plusHours( 8 )

要么…

myJavaUtilDate.toInstant()                // Convert from legacy class to modern class, an `Instant`, a point on the timeline in UTC with resolution of nanoseconds.
              .plus(                      // Do the math, adding a span of time to our moment, our `Instant`. 
                  Duration.ofHours( 8 )   // Specify a span of time unattached to the timeline.
               )                          // Returns another `Instant`. Using immutable objects creates a new instance while leaving the original intact.

使用java.time

Java 8和更高版本中内置的java.time框架取代了旧的Java.util.Date/.Calendar类。那些老班子出了名的麻烦。避免他们。

使用toInstant新添加到java.util.Date 的方法将旧类型转换为新的java.time类型。An InstantUTC时间线上的时刻,分辨率为纳秒

Instant instant = myUtilDate.toInstant();

您可以Instant通过传递TemporalAmount诸如这样来增加时间Duration

Duration duration = Duration.ofHours( 8 );
Instant instantHourLater = instant.plus( duration );

要读取该日期时间,请通过调用生成标准ISO 8601格式的字符串toString

String output = instantHourLater.toString();

您可能希望通过某个区域的挂钟时间的镜头看到这一刻。Instant通过创建,将调整为所需/期望的时区ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

或者,您可以致电plusHours添加您的小时数。进行分区意味着夏时制(DST)和其他异常将代表您处理。

ZonedDateTime later = zdt.plusHours( 8 );

您应该避免使用旧的日期时间类,包括java.util.Date.Calendar。但是,如果您确实需要java.util.Date与尚未针对java.time类型更新的类实现互操作性,请从ZonedDateTimevia 转换Instant。添加到旧类中的新方法促进了与java.time类型之间的转换。

java.util.Date date = java.util.Date.from( later.toInstant() );

有关转换的更多讨论,请参见对问题的回答将java.util.Date转换为“ java.time”类型?


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

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

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


23

Joda-Time

DateTime dt = new DateTime();
DateTime added = dt.plusHours(6);

2
+1不需要这样做,但是如果您要进行更多的日期操作,那么joda time是一个很好的库
Joeri Hendrickx 2010年

3
@JoeriHendrickx如果程序员要为日期添加小时,则可能他们正在执行其他日期时间工作。我认为Joda-Time完全没有必要。设置任何新项目时,我要做的第一件事就是添加Joda-Time。即使Sun和甲骨文同意老java.util.Date和日历需要被淘汰,所以他们增加了新的java.time *包。(由乔达-时间的启发)到Java 8
罗勒布尔克

我在Android上遇到了乔达的麻烦。继续获取ClassNotDefinedException
TheRealChx101,2015年

23

从Java 8开始:

LocalDateTime.now().minusHours(1);

参见LocalDateTimeAPI


4
关闭但不太正确。你应该去一个ZonedDateTime而不是一个LocalDateTime。“本地”是指依赖于任何特定位置,也不依赖于时间轴。就像“圣诞节从2015年12月25日午夜开始”在各个时区一样,这是不同的时刻,在您应用特定时区以获取时间轴上的特定时刻之前没有任何意义。此外,如果没有时区,则无法通过使用LocalDateTime来处理夏令时(DST)和其他异常。比较来看我的答案
罗勒·布尔克

1
还可以java.util.Date按照请求者的要求获取对象ZonedDateTime.toInstant()Date.from()如此处所述stackoverflow.com/a/32274725/5661065
hayduke

16

使用新的java.util.concurrent.TimeUnit类,您可以像这样进行操作

    Date oldDate = new Date(); // oldDate == current time
    Date newDate = new Date(oldDate.getTime() + TimeUnit.HOURS.toMillis(2)); // Adds 2 hours


7

当您的Date对象为Datetime格式时,这是另一段代码。该代码的优点是,如果您提供更多的小时数,则日期也会相应地更新。

    String myString =  "09:00 12/12/2014";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm dd/MM/yyyy");
    Date myDateTime = null;

    //Parse your string to SimpleDateFormat
    try
      {
        myDateTime = simpleDateFormat.parse(myString);
      }
    catch (ParseException e)
      {
         e.printStackTrace();
      }
    System.out.println("This is the Actual Date:"+myDateTime);
    Calendar cal = new GregorianCalendar();
    cal.setTime(myDateTime);

    //Adding 21 Hours to your Date
    cal.add(Calendar.HOUR_OF_DAY, 21);
    System.out.println("This is Hours Added Date:"+cal.getTime());

这是输出:

    This is the Actual Date:Fri Dec 12 09:00:00 EST 2014
    This is Hours Added Date:Sat Dec 13 06:00:00 EST 2014

1
您还可以使用:Calendar cal = Calendar.getInstance();
Stefan Sprenger

4
Date argDate = new Date(); //set your date.
String argTime = "09:00"; //9 AM - 24 hour format :- Set your time.
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm");
String dateTime = sdf.format(argDate) + " " + argTime;
Date requiredDate = dateFormat.parse(dateTime);

4

如果您愿意使用java.time,请使用以下方法添加ISO 8601格式的持续时间:

import java.time.Duration;
import java.time.LocalDateTime;

...

LocalDateTime yourDate = ...

...

// Adds 1 hour to your date.

yourDate = yourDate.plus(Duration.parse("PT1H")); // Java.
// OR
yourDate = yourDate + Duration.parse("PT1H"); // Groovy.  

1
Duration.parse(iso8601duration)很有意思,谢谢,但是您不能+在上使用operator LocalDateTime,您可能需要对其进行编辑。但是.plus(...)确实有效。
qlown

谢谢@qlown,我想+在groovy中工作了,因为这就是我现在使用它的方式。我将相应地修改答案。
丹尼尔(Daniel)

问题是关于一个Date对象的,代表UTC中的特定时刻。您对的使用LocalDateTime无法解决问题。LocalDateTime缺少时区或从UTC偏移的任何概念,因此不能代表一个时刻。这个问题的课程错误。请参阅Instant和LocalDateTime有什么区别?
罗勒·布尔克

@BasilBourque Date对象已弃用。当涉及到时区时,这个问题是模棱两可的,所以我的回答是正确的。此外,你可以换出LocalDateTimeZonedDateTime
丹尼尔(Daniel)

4

您可以使用Joda DateTime API进行操作

DateTime date= new DateTime(dateObj);
date = date.plusHours(1);
dateObj = date.toDate();

在将第一行更改为DateTime之后的工作dateTime = new DateTime(dateObj);
Sundararaj Govindasamy

1

通过使用Java 8类。我们可以如下轻松地操作日期和时间。

LocalDateTime today = LocalDateTime.now();
LocalDateTime minusHours = today.minusHours(24);
LocalDateTime minusMinutes = minusHours.minusMinutes(30);
LocalDate localDate = LocalDate.from(minusMinutes);

问题是关于一个Date对象的,代表UTC中的特定时刻。您对的使用LocalDateTime无法解决问题。LocalDateTime缺少时区或从UTC偏移的任何概念,因此不能代表一个时刻。这个问题的课程错误。请参阅Instant和LocalDateTime有什么区别?
罗勒·布尔克

0

您可以使用Java 8中的LocalDateTime类。例如:

long n = 4;
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.plusHours(n));

问题是关于一个Date对象的,代表UTC中的特定时刻。您对的使用LocalDateTime无法解决问题。LocalDateTime缺少时区或从UTC偏移的任何概念,因此不能代表一个时刻。这个问题的课程错误。请参阅Instant和LocalDateTime有什么区别?
罗勒·布尔克

-1

您可以使用此方法,很容易理解和实现:

public static java.util.Date AddingHHMMSSToDate(java.util.Date date, int nombreHeure, int nombreMinute, int nombreSeconde) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR_OF_DAY, nombreHeure);
    calendar.add(Calendar.MINUTE, nombreMinute);
    calendar.add(Calendar.SECOND, nombreSeconde);
    return calendar.getTime();
}

几年前发布的另一个Answer中已经介绍了这种方法。我看不到这如何增加价值。
罗勒·布尔克

我的建议书的附加值是简单易行,用户只需粘贴并使用它,然后添加小时,分钟或秒,如您所知,初学者的水平有所不同,并且建议的答案是否在简单答案之间结合在一起和进阶答案,将不胜感激:)
Nimpo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.