Добавляете n часов к дате в Java?

136

Как добавить n часов к объекту Date? Я нашел другой пример использования дней в StackOverflow, но все еще не понимаю, как это сделать с часами.

Хорхе Лайнфиеста
источник
3
Используйте joda-time.sourceforge.net , если это возможно.
Бабар
3
Используйте Java 8 Дата и время, если это возможно.
peceps
@Babar FYI, проект Joda-Time в настоящее время находится в режиме обслуживания , и его команда советует перейти на классы java.time . Смотрите Учебник по Oracle .
Василий Бурк

Ответы:

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
5
Излишне упоминать, что вы можете добавить «отрицательные часы»
pramodc84
6
@CurtainDog Using Calendar.add()позаботится об этом автоматически.
Джеспер
6
cal.setTime (new Date ()) не требуется - в javadoc Calendar.getInstance () говорится: «Возвращенный календарь основан на текущем времени в часовом поясе по умолчанию и в локали по умолчанию».
Митрандир
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и Java 9. См. Учебное пособие Oracle .
Василий Бурк
82

Если вы используете Apache Commons / Lang , вы можете сделать это за один шаг, используя DateUtils.addHours():

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

(Исходный объект не изменился)

Шон Патрик Флойд
источник
3
Вы также можете использовать отрицательные часы:DateUtils.addHours(oldDate, -1);
Kaptain
За кулисами это делает именно то, что делает ответ Никиты, но это очень просто и легко читается. Кроме того, если вы уже используете Apache Commons / Lang ... почему бы и нет?
Мэтт
28

Чтобы упростить пример @ Кристофера.

Скажем, у вас есть постоянная

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

Ты можешь написать.

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

Если вы используете long для хранения даты / времени вместо объекта Date, вы можете сделать

long newDate = oldDate + 2 * HOUR;
Питер Лори
источник
27

ТЛ; др

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.time, встроенная в Java 8 и более поздние версии, вытесняет старые классы Java.util.Date/.Calendar. Эти старые классы, как известно, хлопотно. Избежать их.

Используйте toInstantметод, недавно добавленный в java.util.Date, чтобы преобразовать старый тип в новый тип java.time. InstantЭто момент на линии времени в UTC с разрешением наносекунд .

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, выполните конвертацию с ZonedDateTimeпомощью 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.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в java.sql.*классах.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .

Базилик Бурк
источник
23

С Joda-Time

DateTime dt = new DateTime();
DateTime added = dt.plusHours(6);
Бабар
источник
2
+1 немного не нужно для этого, но если вы собираетесь больше манипулировать датами, то joda time - отличная библиотека
Joeri Hendrickx
3
@JoeriHendrickx Если программист добавляет часов в день , то очень вероятно , что они делают другие даты и времени работы. Я не считаю Joda-Time ненужным; первое, что я делаю при настройке любого нового проекта, это добавляю Joda-Time. Даже Sun и Oracle сошлись во мнении, что старые java.util.Date и Calendar должны быть сняты с производства, поэтому они добавили новый пакет java.time. * (Вдохновленный Joda-Time) в Java 8.
Василий Бурк
У меня были проблемы с Йодой на андроиде. Хранится получениеClassNotDefinedException
TheRealChx101
23

Начиная с Java 8:

LocalDateTime.now().minusHours(1);

Смотрите LocalDateTimeAPI .

leventov
источник
4
Близко, но не совсем верно. Вы должны идти за, ZonedDateTimeа не LocalDateTime. «Местный» означает, что он не привязан к какой-либо конкретной местности и не привязан к временной шкале. Например, «Рождество начинается в полночь 25 декабря 2015 года» - это другой момент в разных часовых поясах, который не имеет смысла, пока вы не примените определенный часовой пояс, чтобы получить определенный момент на временной шкале. Кроме того, без часового пояса летнее время (DST) и другие аномалии не будут обрабатываться с таким использованием LocalDateTime. Смотрите мой ответ по сравнению.
Василий Бурк
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
Iain
источник
14

Что-то вроде:

Date oldDate = new Date(); // oldDate == current time
final long hoursInMillis = 60L * 60L * 1000L;
Date newDate = new Date(oldDate().getTime() + 
                        (2L * hoursInMillis)); // Adds 2 hours
Кристофер Хант
источник
1
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и Java 9. См. Учебное пособие Oracle .
Василий Бурк
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
vkrams
источник
1
Вы также можете использовать: Календарь cal = Calendar.getInstance ();
Стефан Спренгер,
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)это интересно, спасибо, но вы не можете использовать оператор +on LocalDateTime, вы можете отредактировать это. Но .plus(...)работает.
qlown
Спасибо @qlown, я думаю, что + работает отлично, потому что именно так я сейчас и использую. Я изменю ответ соответственно.
Даниил
Вопрос об Dateобъекте, который представляет определенный момент в UTC. Ваше использование LocalDateTimeне решает вопрос. LocalDateTimeотсутствует какая-либо концепция часового пояса или смещения от UTC, и поэтому не может представлять момент. Неправильный класс для этой проблемы. Посмотрите, в чем разница между Instant и LocalDateTime?
Базилик Бурк
@BasilBourque Dateобъект устарел. Вопрос двусмысленный, когда речь идет о часовом поясе, поэтому мои ответы остаются. Кроме того, вы можете просто поменять LocalDateTimeна ZonedDateTime.
Даниэль
4

Вы можете сделать это с Joda DateTime API

DateTime date= new DateTime(dateObj);
date = date.plusHours(1);
dateObj = date.toDate();
RaT
источник
Работа после того, как я изменил 1-ую строку на DateTime dateTime = new DateTime (dateObj);
Сундарадж Говиндасамы
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

Вы можете использовать класс LocalDateTime из Java 8. Например:

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();
}
Нимбо
источник
Этот подход уже представлен в другом ответе, опубликованном несколько лет назад. Я не вижу, как это добавляет ценность.
Василий Бурк
Дополнительным преимуществом моего предложения является простота и легкость реализации, пользователь просто вставляет его и использует его, а также добавляет часы, минуты или секунды, как вы знаете, уровень начинающих отличается, и если предлагаемые ответы объединяются между простыми ответами и расширенные ответы это будет заметно :)
Nimpo