Thêm n giờ vào một ngày trong Java?


136

Làm cách nào để thêm n giờ vào đối tượng Date? Tôi đã tìm thấy một ví dụ khác sử dụng ngày trên StackOverflow, nhưng vẫn không hiểu cách thực hiện với hàng giờ.


3
Sử dụng joda-time.sourceforge.net , nếu có thể.
Babar

3
Sử dụng Ngày và Giờ của Java 8 nếu có thể.
peceps

@Babar FYI, dự án Joda-Time hiện đang ở chế độ bảo trì , với nhóm tư vấn di chuyển đến các lớp java.time . Xem Hướng dẫn của Oracle .
Basil Bourque

Câu trả lời:


210

Kiểm tra lớp Lịch. Nó có addphương thức (và một số khác) để cho phép thao tác thời gian. Một cái gì đó như thế này sẽ làm việc.

    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

Kiểm tra API để biết thêm.


4
Chỉ cần cẩn thận nếu bạn đang đối phó với tiết kiệm ánh sáng ban ngày / thời gian mùa hè.
RèmDog

5
Không cần đề cập đến, bạn có thể thêm "giờ âm"
pramodc84

6
@CurtainDog Sử dụng Calendar.add()sẽ tự động chăm sóc điều đó.
Jesper

6
cal.setTime (ngày mới ()) là không cần thiết - javadoc của Calendar.getInstance () nói: "Lịch được trả về dựa trên thời gian hiện tại trong múi giờ mặc định với miền địa phương mặc định."
mithrandir

FYI, các lớp thời gian cũ rắc rối như java.util.Date, java.util.Calendarjava.text.SimpleDateFormathiện đang là di sản , được thay thế bởi các lớp java.time được tích hợp trong Java 8 & Java 9. Xem Hướng dẫn của Oracle .
Basil Bourque

82

Nếu bạn sử dụng Apache Commons / Lang , bạn có thể thực hiện điều đó trong một bước bằng cách sử dụng DateUtils.addHours():

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

(Đối tượng ban đầu không thay đổi)


3
Bạn cũng có thể sử dụng Giờ negativ:DateUtils.addHours(oldDate, -1);
Kaptain 24/2/2015

Đằng sau hậu trường, đây chính xác là những gì câu trả lời của Nikita, nhưng điều này rất đơn giản và dễ đọc. Ngoài ra, nếu bạn đã sử dụng Apache Commons / Lang ... tại sao không?
Matt

28

Để đơn giản hóa ví dụ của @ Christopher.

Nói rằng bạn có một hằng số

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

Bạn có thể viết.

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

Nếu bạn sử dụng lâu để lưu trữ ngày / giờ thay vì đối tượng Ngày, bạn có thể làm

long newDate = oldDate + 2 * HOUR;

26

tl; dr

myJavaUtilDate.toInstant()
              .plusHours( 8 )

Hoặc là…

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.

Sử dụng java.time

Khung công tác java.time được tích hợp vào Java 8 và sau đó thay thế các lớp Java.util.Date/.CalWiki cũ. Những lớp học cũ nổi tiếng là rắc rối. Tránh chúng.

Sử dụng toInstantphương thức mới được thêm vào java.util.Date để chuyển đổi từ loại cũ sang loại java.time mới. An Instantlà một khoảnh khắc trên dòng thời gian trong UTC với độ phân giải nano giây .

Instant instant = myUtilDate.toInstant();

Bạn có thể thêm giờ vào đó Instantbằng cách vượt qua TemporalAmountnhư Duration.

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

Để đọc thời gian đó, hãy tạo Chuỗi theo định dạng ISO 8601 tiêu chuẩn bằng cách gọi toString.

String output = instantHourLater.toString();

Bạn có thể muốn nhìn thấy khoảnh khắc đó qua lăng kính của đồng hồ treo tường của một số khu vực . Điều chỉnh Instantvào múi giờ mong muốn / mong muốn của bạn bằng cách tạo một ZonedDateTime.

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

Ngoài ra, bạn có thể gọi plusHoursđể thêm số giờ của bạn. Được khoanh vùng có nghĩa là Giờ tiết kiệm ánh sáng ban ngày (DST) và các bất thường khác sẽ được xử lý thay cho bạn.

ZonedDateTime later = zdt.plusHours( 8 );

Bạn nên tránh sử dụng các lớp thời gian cũ bao gồm java.util.Date.Calendar. Nhưng nếu bạn thực sự cần một java.util.Datekhả năng tương tác với các lớp chưa được cập nhật cho các loại java.time, hãy chuyển đổi từ ZonedDateTimequa Instant. Các phương thức mới được thêm vào các lớp cũ tạo điều kiện chuyển đổi sang / từ các loại java.time.

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

Để thảo luận thêm về chuyển đổi, hãy xem Câu trả lời của tôi cho Câu hỏi, Chuyển đổi java.util.Date sang loại java java.time nào? .


Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, & SimpleDateFormat.

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Để tìm hiểu thêm, xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*lớp.

Nơi để có được các lớp java.time?

  • Java SE 8 , Java SE 9 và mới hơn
    • Được xây dựng trong.
    • Một phần của API Java tiêu chuẩn với việc triển khai đi kèm.
    • Java 9 thêm một số tính năng nhỏ và sửa lỗi.
  • Java SE 6 Java SE 7
    • Phần lớn chức năng java.time được chuyển ngược lại sang Java 6 & 7 trong ThreeTen-Backport .
  • Android
    • Các phiên bản sau của triển khai gói Android của các lớp java.time.
    • Đối với Android trước đó (<26), các ThreeTenABP dự án thích nghi ThreeTen-backport (nêu trên). Xem Cách sử dụng ThreeTenABP .

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là một nền tảng chứng minh cho các bổ sung có thể trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


23

Với thời gian Joda

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

2
+1 một chút không cần thiết cho việc này, nhưng nếu bạn định thực hiện thao tác hẹn hò nhiều hơn, thời gian joda là một thư viện tuyệt vời
Joeri Hendrickx

3
@JoeriHendrickx Nếu lập trình viên thêm giờ vào một ngày, thì rất có thể họ đang làm công việc hẹn giờ khác. Tôi không xem xét Joda-Time là không cần thiết chút nào; điều đầu tiên tôi làm khi thiết lập bất kỳ dự án mới nào là thêm Joda-Time. Ngay cả Sun và Oracle cũng đồng ý rằng java.util.Date & Lịch cũ cần phải được loại bỏ, vì vậy họ đã thêm gói java.time. * Mới (lấy cảm hứng từ Joda-Time) vào Java 8.
Basil Bourque

Tôi gặp rắc rối với Joda trên Android. Giữ lấyClassNotDefinedException
TheRealChx101

23

Kể từ Java 8:

LocalDateTime.now().minusHours(1);

Xem LocalDateTimeAPI .


4
Đóng nhưng không hoàn toàn đúng. Bạn nên đi cho một ZonedDateTimechứ không phải là một LocalDateTime. "Địa phương" có nghĩa là không bị ràng buộc với bất kỳ địa phương cụ thể nào và không bị ràng buộc với dòng thời gian. Giống như "Giáng sinh bắt đầu vào nửa đêm ngày 25 tháng 12 năm 2015" là một thời điểm khác nhau trên các múi giờ khác nhau, không có nghĩa gì cho đến khi bạn áp dụng một múi giờ cụ thể để có được một khoảnh khắc cụ thể trên dòng thời gian. Hơn nữa, nếu không có Giờ tiết kiệm ánh sáng ban ngày (DST) và các bất thường khác sẽ không được xử lý khi sử dụng LocalDateTime như vậy. Xem câu trả lời của tôi bằng cách so sánh.
Basil Bourque

1
Ngoài ra để có được một java.util.Dateđối tượng như người yêu cầu đã hỏi chúng tôi ZonedDateTime.toInstant()Date.from()như được mô tả ở đây stackoverflow.com/a/32274725/5661065
hayduke

16

Sử dụng lớp java.util.concản.TimeUnit mới, bạn có thể làm như thế này

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

14

Cái gì đó như:

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
FYI, các lớp thời gian cũ rắc rối như java.util.Date, java.util.Calendarjava.text.SimpleDateFormathiện đang là di sản , được thay thế bởi các lớp java.time được tích hợp trong Java 8 & Java 9. Xem Hướng dẫn của Oracle .
Basil Bourque

7

Đây là một đoạn mã khác khi Dateđối tượng của bạn ở định dạng Datetime. Vẻ đẹp của mã này là, Nếu bạn cho số giờ nhiều hơn, ngày cũng sẽ cập nhật tương ứng.

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

Đây là đầu ra:

    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
Bạn cũng có thể sử dụng: Lịch cal = Calendar.getInstance ();
Stefan Sp bôier

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

Nếu bạn sẵn sàng sử dụng java.time, đây là một phương pháp để thêm thời lượng được định dạng 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)Thật thú vị, cảm ơn, nhưng bạn không thể sử dụng toán tử +trên LocalDateTime, bạn có thể muốn chỉnh sửa nó. Nhưng .plus(...)không làm việc.
qlown

Cảm ơn @qlown, tôi đoán + đang hoạt động tốt vì đó là cách tôi đang sử dụng nó. Tôi sẽ sửa đổi câu trả lời cho phù hợp.
Daniel

Câu hỏi là về một Dateđối tượng, đại diện cho một thời điểm cụ thể trong UTC. Việc bạn sử dụng LocalDateTimekhông giải quyết được Câu hỏi. LocalDateTimethiếu bất kỳ khái niệm nào về múi giờ hoặc bù từ UTC và do đó không thể biểu thị một khoảnh khắc. Sai lớp cho vấn đề này. Xem sự khác biệt giữa Instant và LocalDateTime là gì?
Basil Bourque

DateĐối tượng @BasilBourque không được dùng nữa. Câu hỏi mơ hồ khi nói về múi giờ để câu trả lời của tôi đứng vững. Hơn nữa, bạn chỉ có thể trao đổi ra LocalDateTimecho ZonedDateTime.
Daniel

4

Bạn có thể làm điều đó với API Joda DateTime

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

Hoạt động sau khi tôi thay đổi dòng thứ 1 thành DateTime dateTime = new DateTime (dateObj);
Sundararaj Govindasamy

1

bằng cách sử dụng các lớp Java 8. chúng ta có thể thao tác ngày giờ rất dễ dàng như dưới đây.

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

Câu hỏi là về một Dateđối tượng, đại diện cho một thời điểm cụ thể trong UTC. Việc bạn sử dụng LocalDateTimekhông giải quyết được Câu hỏi. LocalDateTimethiếu bất kỳ khái niệm nào về múi giờ hoặc bù từ UTC và do đó không thể biểu thị một khoảnh khắc. Sai lớp cho vấn đề này. Xem sự khác biệt giữa Instant và LocalDateTime là gì?
Basil Bourque

0

Bạn có thể sử dụng lớp LocalDateTime từ Java 8. Ví dụ:

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

Câu hỏi là về một Dateđối tượng, đại diện cho một thời điểm cụ thể trong UTC. Việc bạn sử dụng LocalDateTimekhông giải quyết được Câu hỏi. LocalDateTimethiếu bất kỳ khái niệm nào về múi giờ hoặc bù từ UTC và do đó không thể biểu thị một khoảnh khắc. Sai lớp cho vấn đề này. Xem sự khác biệt giữa Instant và LocalDateTime là gì?
Basil Bourque

-1

Bạn có thể sử dụng phương pháp này, thật dễ hiểu và thực hiện:

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

Cách tiếp cận này đã được trình bày trong một câu trả lời khác được đăng cách đây nhiều năm. Tôi không thấy cách này thêm giá trị nữa.
Basil Bourque

Giá trị gia tăng của đề xuất của tôi là đơn giản và dễ thực hiện, người dùng chỉ cần dán và sử dụng nó và thêm giờ, phút hoặc giây, như bạn biết, mức độ của Người mới bắt đầu khác nhau và nếu câu trả lời được đề xuất kết hợp giữa các câu trả lời đơn giản và câu trả lời nâng cao sẽ rất đáng trân trọng :)
Nimpo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.