เพิ่ม n ชั่วโมงให้กับวันที่ใน Java?


142

ฉันจะเพิ่ม n ชั่วโมงให้กับวัตถุวันที่ได้อย่างไร ฉันพบอีกตัวอย่างหนึ่งที่ใช้วันใน StackOverflow แต่ยังไม่เข้าใจว่าจะทำอย่างไรกับชั่วโมง


3
ใช้joda-time.sourceforge.netถ้าเป็นไปได้
Babar

3
ใช้Java 8 Date and Time ถ้าเป็นไปได้
peceps

@Babar FYI ตอนนี้โปรเจ็กต์Joda-Timeอยู่ในโหมดการบำรุงรักษาโดยทีมงานจะแนะนำการย้ายข้อมูลไปยังคลาสjava.time ดูการสอนโดยออราเคิล
Basil Bourque

คำตอบ:


217

ตรวจสอบCalendarชั้นเรียน มันมี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 plus one hour

ตรวจสอบAPIเพิ่มเติม


4
ระวังถ้าคุณกำลังจัดการกับเวลาออมแสง / ฤดูร้อน
CurtainDog

6
ไม่จำเป็นต้องพูดถึงคุณสามารถเพิ่ม "ชั่วโมงเชิงลบ" ได้
pramodc84

6
@CurtainDog การใช้งานCalendar.add()จะดูแลโดยอัตโนมัติ
Jesper

6
cal.setTime (วันที่ใหม่ ()) ไม่จำเป็น - javadoc ของ Calendar.getInstance () ระบุว่า: "ปฏิทินที่ส่งคืนจะขึ้นอยู่กับเวลาปัจจุบันในเขตเวลาเริ่มต้นที่มีภาษาเริ่มต้น"
mithrandir

FYI, ลำบากเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และ Java 9 โปรดดูที่การสอนโดยออราเคิล
Basil Bourque

87

หากคุณใช้Apache Commons / Langคุณสามารถทำได้ในขั้นตอนเดียวโดยใช้DateUtils.addHours():

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

(วัตถุเดิมไม่เปลี่ยนแปลง)


3
คุณยังสามารถใช้ Negativ Hours:DateUtils.addHours(oldDate, -1);
Kaptain

เบื้องหลังสิ่งนี้ทำตามคำตอบของ Nikita ได้อย่างแท้จริง แต่นี่ง่ายมากและอ่านง่าย นอกจากนี้หากคุณใช้ Apache Commons / Lang อยู่แล้ว ... ทำไมไม่?
Matt

30

เพื่อลดความซับซ้อนของตัวอย่างของ @ Christopher

สมมติว่าคุณมีค่าคงที่

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;

28

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

หากต้องการอ่านว่าวันเวลาสร้าง String ในรูปแบบมาตรฐาน 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 วันที่ประเภท "java.time" คืออะไร .


เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, และCalendarSimpleDateFormat

โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำให้ย้ายไปที่คลาสjava.time

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปก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-ย้ายกลับ
  • Android
    • การติดตั้งบันเดิล Android เวอร์ชันที่ใหม่กว่าของคลาส java.time
    • สำหรับก่อนหน้านี้ Android (<26) ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีใช้ 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 เป็นห้องสมุดที่ยอดเยี่ยม
Joeri Hendrickx

3
@JoeriHendrickx หากโปรแกรมเมอร์ที่จะเพิ่มชั่วโมงวันที่แล้วมากมีแนวโน้มที่พวกเขากำลังทำผลงานวันที่เวลาอื่น ๆ ฉันไม่คิดว่าJoda-Timeไม่จำเป็นเลย สิ่งแรกที่ฉันทำเมื่อตั้งค่าโปรเจ็กต์ใหม่คือเพิ่ม Joda-Time แม้แต่ Sun และ Oracle ก็เห็นพ้องกันว่า java.util.Date & Calendar แบบเก่าจะต้องเลิกใช้ดังนั้นพวกเขาจึงเพิ่มแพ็คเกจ java.time. *ใหม่(ได้รับแรงบันดาลใจจาก Joda-Time) ไปยัง Java 8
Basil Bourque

ฉันมีปัญหากับ Joda บน Android รับClassNotDefinedException
TheRealChx101

23

ตั้งแต่ Java 8:

LocalDateTime.now().minusHours(1);

ดูAPILocalDateTime


4
ปิด แต่ไม่ค่อยถูกต้อง คุณควรเลือกZonedDateTimeใช้ไฟล์LocalDateTime. "ท้องถิ่น" หมายถึงไม่เชื่อมโยงกับท้องถิ่นใดพื้นที่หนึ่งและไม่เชื่อมโยงกับไทม์ไลน์ เช่นเดียวกับ "คริสต์มาสเริ่มเวลาเที่ยงคืนของวันที่ 25 ธันวาคม 2015" เป็นช่วงเวลาที่แตกต่างกันในเขตเวลาต่างๆโดยไม่มีความหมายจนกว่าคุณจะใช้เขตเวลาใดเขตเวลาหนึ่งเพื่อให้ได้ช่วงเวลาที่เฉพาะเจาะจงบนเส้นเวลา นอกจากนี้หากไม่มีโซนเวลา Daylight Saving Time (DST) และความผิดปกติอื่น ๆ จะไม่ได้รับการจัดการด้วยการใช้ LocalDateTime ดังกล่าว ดูคำตอบของฉันโดยเปรียบเทียบ
Basil Bourque

1
นอกจากนี้เพื่อรับjava.util.Dateวัตถุตามที่ผู้ร้องขอถามเราZonedDateTime.toInstant()และDate.from()ตามที่อธิบายไว้ที่นี่stackoverflow.com/a/32274725/5661065
hayduke


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
FYI, ลำบากเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และ Java 9 โปรดดูที่การสอนโดยออราเคิล
Basil Bourque

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)เป็นที่น่าสนใจขอบคุณ แต่คุณไม่สามารถใช้ประกอบการ+บนLocalDateTimeคุณอาจต้องการที่จะแก้ไขว่า แต่.plus(...)ไม่ได้ผล
qlown

ขอบคุณ @qlown ฉันเดาว่า + ใช้งานได้ดีเพราะนั่นคือวิธีที่ฉันใช้ตอนนี้ ฉันจะแก้ไขคำตอบตามนั้น
Daniel

คำถามเป็นเรื่องเกี่ยวกับDateวัตถุซึ่งแสดงถึงช่วงเวลาที่เฉพาะเจาะจงใน UTC การใช้งานของคุณLocalDateTimeล้มเหลวในการตอบคำถาม LocalDateTimeไม่มีแนวคิดเกี่ยวกับเขตเวลาหรือ offset-from-UTC ดังนั้นจึงไม่สามารถแสดงช่วงเวลาได้ ชั้นผิดสำหรับปัญหานี้ ดูความแตกต่างระหว่าง Instant และ LocalDateTime คืออะไร
Basil Bourque

Dateวัตถุ@BasilBourque เลิกใช้แล้ว คำถามไม่ชัดเจนเมื่อพูดถึงเขตเวลาดังนั้นคำตอบของฉันจึงยืน นอกจากนี้คุณสามารถเปลี่ยนLocalDateTimeเป็นZonedDateTimeไฟล์.
Daniel

4

คุณสามารถทำได้ด้วย Joda DateTime API

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

ทำงานหลังจากที่ฉันเปลี่ยนบรรทัดที่ 1 เป็น DateTime dateTime = 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ไม่มีแนวคิดเกี่ยวกับเขตเวลาหรือ offset-from-UTC ดังนั้นจึงไม่สามารถแสดงช่วงเวลาได้ ชั้นผิดสำหรับปัญหานี้ ดูความแตกต่างระหว่าง Instant และ LocalDateTime คืออะไร
Basil Bourque

0

คุณสามารถใช้คลาส LocalDateTime จาก Java 8 ได้เช่น:

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

1
คำถามเป็นเรื่องเกี่ยวกับDateวัตถุซึ่งแสดงถึงช่วงเวลาที่เฉพาะเจาะจงใน UTC การใช้งานของคุณLocalDateTimeล้มเหลวในการตอบคำถาม LocalDateTimeไม่มีแนวคิดเกี่ยวกับเขตเวลาหรือ offset-from-UTC ดังนั้นจึงไม่สามารถแสดงช่วงเวลาได้ ชั้นผิดสำหรับปัญหานี้ ดูความแตกต่างระหว่าง Instant และ LocalDateTime คืออะไร
Basil Bourque

-2

คุณสามารถใช้วิธีนี้เข้าใจง่ายและนำไปใช้:

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

1
แนวทางนี้ได้นำเสนอแล้วในคำตอบอื่นที่โพสต์เมื่อหลายปีก่อน ฉันไม่เห็นว่าสิ่งนี้เพิ่มมูลค่าอีกต่อไปอย่างไร
Basil Bourque

มูลค่าเพิ่มของข้อเสนอของฉันคือความเรียบง่ายและใช้งานง่ายผู้ใช้เพียงแค่วางและใช้งานและเพิ่มชั่วโมงนาทีหรือวินาทีดังที่คุณทราบระดับของผู้เริ่มต้นจะแตกต่างกันไปและหากคำตอบที่เสนอรวมกันระหว่างคำตอบง่ายๆ และคำตอบขั้นสูงจะเป็นที่ชื่นชม :)
Nimpo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.