Dodanie n godzin do daty w Javie?

136

Jak dodać n godzin do obiektu Date? Znalazłem inny przykład, używając dni w StackOverflow, ale nadal nie rozumiem, jak to zrobić z godzinami.

Jorge Lainfiesta
źródło
3
Jeśli to możliwe, użyj joda-time.sourceforge.net .
Babar
3
Jeśli to możliwe, używaj daty i godziny Java 8 .
peceps
@Babar FYI, projekt Joda-Time jest teraz w trybie konserwacji , a zespół doradza migrację do klas java.time . Zobacz samouczek firmy Oracle .
Basil Bourque

Odpowiedzi:

210

Sprawdź klasę kalendarza. Ma addmetodę (i kilka innych) pozwalającą na manipulację czasem. Coś takiego powinno działać.

    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

Sprawdź API, aby uzyskać więcej informacji.

Nikita Rybak
źródło
4
Po prostu bądź ostrożny, jeśli masz do czynienia z czasem letnim / letnim.
CurtainDog,
5
Nie trzeba wspominać, że możesz dodać „ujemne godziny”
pramodc84
6
@CurtainDog Using Calendar.add()zajmuje się tym automatycznie.
Jesper
6
cal.setTime (new Date ()) nie jest potrzebne - javadoc funkcji Calendar.getInstance () mówi: „Zwrócony kalendarz jest oparty na bieżącym czasie w domyślnej strefie czasowej z domyślnymi ustawieniami regionalnymi”.
mithrandir,
FYI, kłopotliwe stare klasy daty i godziny, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz starsze , zastąpione przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek Oracle .
Basil Bourque
82

Jeśli używasz Apache Commons / Lang , możesz to zrobić w jednym kroku za pomocą DateUtils.addHours():

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

(Oryginalny obiekt pozostaje niezmieniony)

Sean Patrick Floyd
źródło
3
Możesz również użyć negatywnych godzin:DateUtils.addHours(oldDate, -1);
Kaptain
Za kulisami robi to dokładnie to samo, co odpowiedź Nikity, ale jest bardzo proste i łatwe do odczytania. Ponadto, jeśli już używasz Apache Commons / Lang ... dlaczego nie?
Matt,
28

Aby uprościć przykład @ Christophera.

Powiedz, że masz stałą

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

Możesz pisać.

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

Jeśli używasz long do przechowywania daty / czasu zamiast obiektu Date, możesz to zrobić

long newDate = oldDate + 2 * HOUR;
Peter Lawrey
źródło
26

tl; dr

myJavaUtilDate.toInstant()
              .plusHours( 8 )

Lub…

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.

Korzystanie z java.time

Struktura java.time wbudowana w Javę 8 i późniejsze zastępuje stare klasy Java.util.Date/.Calendar. Te stare klasy są bardzo kłopotliwe. Unikaj ich.

Użyj toInstantmetody nowo dodanej do java.util.Date, aby przekonwertować stary typ na nowy typ java.time. Na Instantlinii czasu w UTC znajduje się moment z rozdzielczością nanosekund .

Instant instant = myUtilDate.toInstant();

Możesz dodać do tego godziny, Instantpodając TemporalAmountnp Duration.

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

Aby odczytać tę datę i godzinę, wygeneruj ciąg w standardowym formacie ISO 8601, wywołując toString.

String output = instantHourLater.toString();

Możesz chcieć zobaczyć ten moment przez pryzmat zegara ściennego w jakimś regionie . Ustaw Instantżądaną / oczekiwaną strefę czasową, tworząc plik ZonedDateTime.

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

Możesz też zadzwonić, plusHoursaby dodać liczbę godzin. Bycie strefowym oznacza, że ​​czas letni (DST) i inne anomalie będą obsługiwane w Twoim imieniu.

ZonedDateTime later = zdt.plusHours( 8 );

Należy unikać używania starych klas daty i godziny, w tym java.util.Datei .Calendar. Ale jeśli naprawdę potrzebujesz java.util.Datewspółdziałania z klasami, które nie zostały jeszcze zaktualizowane dla typów java.time, przekonwertuj z ZonedDateTimevia Instant. Nowe metody dodane do starych klas ułatwiają konwersję do / z typów java.time.

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

Więcej informacji na temat konwersji można znaleźć w sekcji Moja odpowiedź na pytanie, Konwersja java.util.Date na jaki typ „java.time”? .


Informacje o java.time

Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date, Calendar, i SimpleDateFormat.

Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas.

Skąd wziąć klasy java.time?

Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .

Basil Bourque
źródło
23

Z Joda-Time

DateTime dt = new DateTime();
DateTime added = dt.plusHours(6);
Babar
źródło
2
+1 trochę niepotrzebne, ale jeśli zamierzasz robić więcej manipulacji datami, czas joda to świetna biblioteka
Joeri Hendrickx
3
@JoeriHendrickx Jeśli programator jest dodawanie godzin do daty, to bardzo prawdopodobne, że robią inne prace data-czas. W ogóle nie uważam Joda-Time za niepotrzebną; Pierwszą rzeczą, którą robię podczas tworzenia nowego projektu, jest dodanie Joda-Time. Nawet Sun i Oracle zgodziły się, że stary java.util.Date & Calendar musi zostać wycofany, więc dodali nowy pakiet java.time. * (Zainspirowany Joda-Time) do Java 8.
Basil Bourque
Miałem problem z Jodą na Androidzie. Utrzymane w zdobywaniuClassNotDefinedException
TheRealChx101
23

Od wersji Java 8:

LocalDateTime.now().minusHours(1);

Zobacz LocalDateTimeAPI .

Leventov
źródło
4
Blisko, ale nie do końca. Powinieneś wybrać ZonedDateTimeraczej niż LocalDateTime. W „lokalny” oznacza nie związane z żadnym konkretnym obszarze, a nie przywiązany do czasu. Podobnie jak „Boże Narodzenie zaczyna się o północy 25 grudnia 2015 r.” To inny moment w różnych strefach czasowych, bez znaczenia, dopóki nie zastosujesz określonej strefy czasowej, aby wyświetlić określony moment na osi czasu. Ponadto bez strefy czasowej czas letni (DST) i inne anomalie nie będą obsługiwane przy takim użyciu funkcji LocalDateTime. Zobacz moją odpowiedź w porównaniu.
Basil Bourque
1
Również po to, aby uzyskać java.util.Dateobiekt, o który prosił nas ZonedDateTime.toInstant()Date.from()
żądający
16

Używając nowej klasy java.util.concurrent.TimeUnit możesz to zrobić w ten sposób

    Date oldDate = new Date(); // oldDate == current time
    Date newDate = new Date(oldDate.getTime() + TimeUnit.HOURS.toMillis(2)); // Adds 2 hours
Iain
źródło
14

Coś jak:

Date oldDate = new Date(); // oldDate == current time
final long hoursInMillis = 60L * 60L * 1000L;
Date newDate = new Date(oldDate().getTime() + 
                        (2L * hoursInMillis)); // Adds 2 hours
Christopher Hunt
źródło
1
FYI, kłopotliwe stare klasy daty i godziny, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz starsze , zastąpione przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek Oracle .
Basil Bourque
7

To kolejny fragment kodu, gdy Dateobiekt jest w formacie Datetime. Piękno tego kodu polega na tym, że jeśli podasz więcej godzin, data również zostanie odpowiednio zaktualizowana.

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

Oto wynik:

    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
źródło
1
Możesz również użyć: 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);
Ghost Rider
źródło
4

Jeśli chcesz skorzystać java.time, oto metoda dodawania czasów trwania w formacie 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.  
Daniel
źródło
1
Duration.parse(iso8601duration)jest interesujący, dzięki, ale nie możesz używać operatora +na LocalDateTime, możesz chcieć to edytować. Ale .plus(...)działa.
qlown
Dzięki @qlown, myślę, że + działa w groovy, ponieważ tak go teraz używam. Odpowiednio zmodyfikuję odpowiedź.
Daniel
Pytanie dotyczy Dateobiektu, który reprezentuje określony moment w UTC. Twoje użycie LocalDateTimenie odpowiada na pytanie. LocalDateTimenie ma pojęcia strefy czasowej ani przesunięcia w stosunku do UTC, a zatem nie może reprezentować momentu. Niewłaściwa klasa dla tego problemu. Zobacz, jaka jest różnica między funkcją Instant a LocalDateTime?
Basil Bourque
DateObiekt @BasilBourque jest przestarzały. Pytanie jest niejednoznaczne, jeśli chodzi o strefę czasową, więc moje odpowiedzi są aktualne. Co więcej, możesz po prostu zamienić się LocalDateTimena ZonedDateTime.
Daniel
4

Możesz to zrobić za pomocą Joda DateTime API

DateTime date= new DateTime(dateObj);
date = date.plusHours(1);
dateObj = date.toDate();
Szczur
źródło
Praca po zmianie pierwszej linii na DateTime dateTime = new DateTime (dateObj);
Sundararaj Govindasamy
1

przy użyciu klas Java 8. możemy bardzo łatwo manipulować datą i godziną, jak poniżej.

LocalDateTime today = LocalDateTime.now();
LocalDateTime minusHours = today.minusHours(24);
LocalDateTime minusMinutes = minusHours.minusMinutes(30);
LocalDate localDate = LocalDate.from(minusMinutes);
Abdul Gafoor
źródło
Pytanie dotyczy Dateobiektu, który reprezentuje określony moment w UTC. Twoje użycie LocalDateTimenie odpowiada na pytanie. LocalDateTimenie ma pojęcia strefy czasowej ani przesunięcia w stosunku do UTC, a zatem nie może reprezentować momentu. Niewłaściwa klasa dla tego problemu. Zobacz, jaka jest różnica między funkcją Instant a LocalDateTime?
Basil Bourque
0

Możesz użyć klasy LocalDateTime z Java 8. Na przykład:

long n = 4;
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.plusHours(n));
Sajit Gupta
źródło
Pytanie dotyczy Dateobiektu, który reprezentuje określony moment w UTC. Twoje użycie LocalDateTimenie odpowiada na pytanie. LocalDateTimenie ma pojęcia strefy czasowej ani przesunięcia w stosunku do UTC, a zatem nie może reprezentować momentu. Niewłaściwa klasa dla tego problemu. Zobacz, jaka jest różnica między funkcją Instant a LocalDateTime?
Basil Bourque
-1

Możesz użyć tej metody, jest łatwa do zrozumienia i wdrożenia:

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
źródło
To podejście jest już przedstawione w innej odpowiedzi opublikowanej lata temu. Nie widzę już, jak to dodaje wartości.
Basil Bourque
Wartością dodaną mojej propozycji jest prostota i łatwość implementacji, wystarczy ją wkleić i wykorzystać oraz dodać godziny, minuty czy sekundy, jak wiadomo poziom Początkujących jest różny i czy proponowane odpowiedzi łączą się z prostymi odpowiedziami i zaawansowane odpowiedzi będą odczuwalne :)
Nimpo