ฉันจะรับ Date โดยไม่ใช้เวลาใน Java ได้อย่างไร


235

การดำเนินการต่อจากโปรแกรม Stack Overflow คำถามJava เพื่อรับวันที่ปัจจุบันโดยไม่มีการประทับเวลา :

วิธีที่มีประสิทธิภาพมากที่สุดในการรับวัตถุวันที่ไม่มีเวลาคืออะไร? มีวิธีอื่นนอกเหนือจากสองสิ่งนี้หรือไม่?

// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));

// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();

อัปเดต :

  1. ฉันรู้เกี่ยวกับJoda-Time ; ฉันแค่พยายามหลีกเลี่ยงห้องสมุดเพิ่มเติมสำหรับงานง่าย ๆ (ฉันคิดว่า) แต่จากคำตอบจนถึงตอนนี้ Joda-Time นั้นได้รับความนิยมอย่างมากดังนั้นฉันจึงอาจพิจารณา

  2. โดยที่มีประสิทธิภาพฉันหมายความว่าฉันต้องการหลีกเลี่ยงStringการสร้างวัตถุชั่วคราวตามที่ใช้โดยmethod 1ในขณะเดียวกันmethod 2ดูเหมือนแฮ็คแทนที่จะเป็นวิธีการแก้ปัญหา


1
ประสิทธิภาพสูงหรือไม่ คุณต้องการประสิทธิภาพมากกว่าสิ่งที่จัดให้เช่นโดยวิธีที่ 1?
Johan Sjöberg

2
"ประสิทธิภาพ" หมายถึงอะไร โดยทั่วไปแล้ววันที่จะพิมพ์ยาวคุณไม่สามารถทำได้ในหน่วยความจำน้อยกว่านั้น ถ้าคุณหมายถึง "สะดวก" เวลาของ JODA คือหนทางที่จะไป
millimoose

3
+1 ตรงคำถามที่ผมมี
Alba Mendez

1
ฉันชอบวิธีที่ 2 สร้างวิธีการคงที่ในคลาสยูทิลิตี้และเพียงแค่ใช้มัน ฉันได้รับวิธีการนี้มานานหลายปี
Wilson Freitas

1
การวาง Nitpicking ใน "update 1" ของคุณ: ถ้าเป็น "งานง่าย ๆ " ฉันเดาว่า Sun จะไม่ได้มากับ API ที่น่ากลัวและไม่มีประสิทธิภาพและคุณ (และคนอื่น ๆ อีกมากมาย) จะไม่ถามคำถามนั้น เลย ;-)
Flávio Etrusco

คำตอบ:


108

คุณต้องใช้อย่างแน่นอนjava.util.Date? ฉันอยากจะแนะนำอย่างละเอียดว่าคุณใช้Joda Timeหรือjava.timeแพ็คเกจจาก Java 8 แทน โดยเฉพาะอย่างยิ่งในขณะที่วันที่และปฏิทินเสมอแทนทันทีโดยเฉพาะอย่างยิ่งในเวลาที่ไม่มีแนวคิดเช่น "เพียงแค่วันที่" Joda เวลาไม่มีประเภทเป็นตัวแทนนี้ ( LocalDate) รหัสของคุณจะชัดเจนมากขึ้นถ้าคุณสามารถใช้ประเภทที่แสดงถึงสิ่งที่คุณพยายามทำจริง ๆ

มีเหตุผลอื่น ๆ อีกมากมายที่จะใช้ Joda Time หรือjava.timeแทนที่จะเป็นjava.utilชนิดในตัว- โดยทั่วไปแล้วพวกเขาจะดีกว่า APIs คุณสามารถแปลงเป็น / จาก a java.util.Dateที่ขอบเขตของรหัสของคุณเองหากคุณต้องการเช่นสำหรับการโต้ตอบกับฐานข้อมูล


75
ในแอปพลิเคชันองค์กรเราไม่มีตัวเลือกในการเพิ่ม / ใช้ไลบรารีอื่น ๆ ฉันขอขอบคุณตัวชี้ไปที่ Joda Time แต่จริงๆแล้วมันไม่ใช่คำตอบของปัญหาดั้งเดิมในการรับส่วนวันที่โดยใช้ Java มาตรฐาน ขอบคุณ Upvoting คำตอบของ Chathuranga
noogrub

3
@noogrub: คำตอบของ Chathugranga ไม่ได้ตอบคำถามเดิมซึ่งถามเกี่ยวกับวิธีรับDateวัตถุ - คำตอบนั้นจะจัดรูปแบบวันที่เป็นสตริงซึ่งไม่ใช่สิ่งเดียวกัน โดยพื้นฐานแล้วการถามว่าวันที่เปิดDateอยู่นั้นเป็นคำถามที่ไม่มีความหมายหากไม่มีข้อมูลเพิ่มเติม: เขตเวลาและระบบปฏิทินที่คุณกำลังใช้
Jon Skeet

7
"ในแอปพลิเคชันองค์กรเราไม่มีตัวเลือกในการเพิ่ม / ใช้ไลบรารีอื่น ๆ " จริงเหรอ คุณแนะนำให้คุณไม่สามารถใช้ libs ของบุคคลที่สามได้หรือไม่?
Brian Agnew

3
@BrianAgnew ความคิดเห็นของ noogrub ดูเหมือนว่าจะเกี่ยวข้องกับข้อ จำกัด ที่ไม่ใช่เทคโนโลยีฉันคิดว่า
Jose_GD

3
จากมุมมองของวันนี้: " Joda-Timeคือวันที่และเวลามาตรฐานของพฤตินัยสำหรับ Java ก่อน Java SE 8 ตอนนี้ผู้ใช้จะถูกขอให้ย้ายไปยัง java.time (JSR-310)"
Drux

66

นี่คือสิ่งที่ฉันเคยได้รับวันที่วันนี้ด้วยเวลาที่กำหนด00:00:00:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

Date today = new Date();

Date todayWithZeroTime = formatter.parse(formatter.format(today));

28
สิ่งนี้แตกต่างจาก "วิธีที่ 1" ที่เสนอไปแล้วในคำถามเดิมอย่างไร
Chris

ไม่ได้ระบุถึงสิ่งที่เกิดขึ้นในเขตเวลา (จากซ้ายไปเป็นเขตเวลาเริ่มต้นโดยพลการของ JVM)
ดาร์เรล Teague

58

คุณสามารถใช้DateUtils.truncateจากไลบรารี Apache Commons

ตัวอย่าง:

DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)

3
หากคุณกำลังจะเพิ่มห้องสมุดใหม่ให้เป็น Joda แทน Apache Commons
Dibbeke

6
+1 @Dibbeke ความแตกต่างไม่ใช่แค่ว่าคุณจะเพิ่มห้องสมุดหนึ่งแทนที่จะเป็นห้องสมุดอื่น บางครั้งเราไม่ต้องการที่จะเรียนรู้ห้องสมุดใหม่ทั้งหมดสำหรับงานที่ไม่สำคัญในการตัดเวลาจากวันที่ หรือไม่ต้องการให้มีรหัสที่ผสม Date / Calendar กับ Joda Date โดยใช้บางครั้งเป็นแบบเก่าและแบบหลัง หรือไม่สามารถจ่าย / ปรับแทนรหัสวันที่ / ปฏิทินที่ใช้งานได้ดีทั้งหมดด้วยห้องสมุดอื่นเพื่อจุดประสงค์เล็กน้อย ในขณะที่การแนะนำ Joda นั้นดีอย่างแน่นอนเพราะเหนือกว่าอย่างเห็นได้ชัดและ The Right Thing บางครั้งชีวิตจริงก็เตะเข้ามา
SantiBailors

Genius! ช่วยฉันเป็นจำนวนมาก
Thiesen

37

มีวิธีอื่นนอกเหนือจากสองสิ่งนี้หรือไม่?

ใช่แล้ว

LocalDate.now( 
    ZoneId.of( "Pacific/Auckland" ) 
)

java.time

Java 8 และต่อมาก็มาพร้อมกับใหม่แพคเกจ java.timeในตัว ดูการสอน ฟังก์ชันการทำงานของ java.time ส่วนใหญ่ถูกแบ็คพอร์ตไปยัง Java 6 & 7 ในThreeTen-Backportและปรับใช้กับ Android ในThreeTenABPเพิ่มเติม

คล้ายกับJoda-Time , java.time นำเสนอLocalDateคลาสเพื่อแสดงค่าวันที่เท่านั้นโดยไม่มีเวลาของวันและไม่มีเขตเวลา

โปรดทราบว่าเขตเวลามีความสำคัญต่อการพิจารณาวันที่เฉพาะ ยกตัวอย่างเช่นเมื่อถึงเที่ยงคืนในปารีสวันที่ดังกล่าวจะยังคงเป็น "เมื่อวาน" ในมอนทรีออล

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;

โดยค่าเริ่มต้น java.time ใช้มาตรฐาน ISO 8601ในการสร้างการแสดงสตริงของค่าวันที่หรือเวลา (คล้ายคลึงกันกับ Joda เวลาอีก.) ดังนั้นเพียงโทรเพื่อสร้างข้อความเช่นtoString()2015-05-21

String output = today.toString() ; 

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

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

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

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310

จะรับคลาส java.time ได้ที่ไหน?

  • Java SE 8 , Java SE 9และใหม่กว่า
    • Built-in
    • เป็นส่วนหนึ่งของ Java API มาตรฐานที่มีการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android
    • การใช้งานชุดบันเดิล Android รุ่นต่อมาของคลาส java.time
    • สำหรับก่อนหน้านี้ของ Android ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีการใช้ ThreeTenABP … .

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โครงการนี้เป็นพื้นฐานที่พิสูจน์ได้สำหรับการเพิ่มเติมในอนาคตไปยัง java.time คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


1
ขอขอบคุณสำหรับการกล่าวขวัญโซนเวลา มันไม่ได้เกิดขึ้นกับฉันว่า "วันนี้เป็นวันอะไร" ไม่ใช่แนวคิดที่สมบูรณ์
ToolmakerSteve

@ToolmakerSteve การรับวันที่เกี่ยวข้องกับเขตเวลาเสมอ แต่เคล็ดลับคือถ้าคุณไม่ระบุเขตเวลาเขตเวลาเริ่มต้นปัจจุบันของ JVM ของคุณจะถูกนำไปใช้โดยอัตโนมัติในการกำหนดวันที่ ยิ่งไปกว่านั้นเขตเวลาเริ่มต้นปัจจุบันของ JVM สามารถเปลี่ยนแปลงได้ตลอดเวลา ! โค้ดใด ๆ ในเธรดใด ๆ ของแอพใด ๆ ภายใน JVM สามารถเรียกใช้TimeZone.setDefaultในระหว่างรันไทม์และส่งผลกระทบต่อโค้ดอื่น ๆ ทั้งหมดที่รันใน JVM นั้นทันที คุณธรรมของเรื่องราว: ระบุเขตเวลาเสมอ
Basil Bourque

22

วิธีที่ตรงไปตรงมาที่สุด:

long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);

5
สำหรับฉันปัจจุบันนี้: "Sat 19 ก.พ. 01 : 00: 00 CET 2011" หากคุณต้องการใช้สิ่งนั้นจะใช้เฉพาะกับ UTC
Chris Lercher

4
บรรทัดที่ 3 ไม่long dateOnly = (currentTime / millisInDay) * millisInDay;เหมือนกับการเขียนlong dateOnly = currentTime;ใช่ไหม
Chris

5
ไม่ใช่เพราะเลขจำนวนเต็ม ลองคิดดูเช่น Math.floor (currentTime / millisInDay) * millisInDay เขาตั้งเวลาอย่างมีประสิทธิภาพเป็น 00:00:00
นิโคลัส Flynt

2
โซลูชันนี้อาจใช้ได้กับแอปพลิเคชันส่วนใหญ่ แต่ได้รับการเตือนว่าวันหนึ่ง ๆ ที่มี 60 * 60 * 24 * 1,000 นั้นไม่เป็นความจริงเสมอไป เช่นคุณสามารถมีวินาทีกระโดดในบางวัน
Pierre-Antoine

1
นี่เป็นวิธีที่ป้านที่สุดและไม่แนะนำให้ใช้กับวิธี 1 และ 2-line ที่ชัดเจนและรัดกุม
Darrell Teague

22

คำตอบมาตรฐานคำถามเหล่านี้คือการใช้Joda เวลา API นั้นดีกว่าและถ้าคุณใช้ตัวจัดรูปแบบและตัวแยกวิเคราะห์คุณสามารถหลีกเลี่ยงการขาดความปลอดภัยของเธรดSimpleDateFormatได้

การใช้ Joda หมายความว่าคุณสามารถทำได้โดยง่าย:

LocalDate d = new LocalDate();

Update ::การใช้ java 8 สามารถทำได้โดยใช้

LocalDate date = LocalDate.now();

แพ็คเกจ java.time ใหม่ใน Java 8 ยังมีLocalDateคลาสคล้ายกับ Joda-Time
Basil Bourque

1
เป็นการดีที่คุณจะส่งต่อDateTimeZoneไปยังตัวสร้าง LocalDate นั้น การกำหนดวันที่ปัจจุบันขึ้นอยู่กับเขตเวลาเนื่องจากปารีสเริ่มวันที่ใหม่ก่อนหน้ามอนทรีออล หากคุณข้ามเขตเวลาระบบจะใช้เขตเวลาเริ่มต้นของ JVM ของคุณ มักจะดีกว่าที่จะระบุกว่าพึ่งพาเริ่มต้น
Basil Bourque

8

นี่เป็นวิธีง่ายๆในการทำ:

Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));

4
คำตอบนี้ไม่สามารถตอบคำถามได้ การได้รับสตริงที่จัดรูปแบบไม่ใช่เป้าหมาย
Basil Bourque

7

มันไม่สมเหตุสมผลเลยที่จะพูดถึงวันที่โดยไม่มีการประทับเวลาที่เกี่ยวข้องกับรูทีน Date ใน Java runtime มาตรฐานเนื่องจากแผนที่จะจับคู่กับมิลลิวินาทีที่เฉพาะเจาะจงและไม่ใช่วันที่ มิลลิวินาทีที่กล่าวมานั้นมีอยู่ภายในเวลาหนึ่งวันซึ่งทำให้เสี่ยงต่อปัญหาเขตเวลาเช่น Daylight Saving Time และการปรับปฏิทินอื่น ๆ ดูทำไมการลบสองครั้งนี้ (ในปี 1927) จึงให้ผลลัพธ์ที่แปลกประหลาด สำหรับตัวอย่างที่น่าสนใจ

หากคุณต้องการทำงานกับวันที่แทนมิลลิวินาทีคุณต้องใช้อย่างอื่น สำหรับ Java 8 มีชุดวิธีการใหม่ที่ให้สิ่งที่คุณต้องการอย่างแท้จริง สำหรับ Java 7 และก่อนหน้านี้ใช้http://www.joda.org/joda-time/


3
หมายเหตุ: วิธีการที่กล่าวว่า "วันที่เวลาเที่ยงคืน" ไม่สามารถจัดการเวลาออมแสงและเขตเวลาหลายแห่งได้เป็นอย่างดี
Thorbjørn Ravn Andersen

ฉันยืนยันว่าฉันกำลังเพิ่มวันที่โดยหนึ่งวันในแอปของฉันและเรียนรู้เกี่ยวกับสิ่งนี้ด้วยรายงานข้อผิดพลาดจากผู้ใช้ในเขตเวลาด้วย DST (ประเทศของฉันไม่ได้ใช้ DST) ในวันที่ DST เริ่มต้นแอพของฉันเพิ่ม 11 ชั่วโมงแทน 12 บางทีการใช้เวลาเที่ยงเป็นชั่วโมงสำหรับวันที่ "ไม่มีเวลา" ดีกว่าไหม
Jose_GD

1
@Jose_GD แฮ็คยังดีที่สุด คุณอาจพบว่าyoutube.com/watch?v=-5wpm-gesOYสนุกสนาน
Thorbjørn Ravn Andersen

@ Thorbjorn คุณพูดถูกเพียงแค่ต้องการหลีกเลี่ยง JodaTime เพราะเพิ่มห้องสมุดสำหรับเสียงที่มีคุณสมบัติเกินบรรยายเพียงหนึ่งข้อสำหรับฉัน ฉันรู้เกี่ยวกับวิดีโอนั้นตลกดีจริง ๆ
Jose_GD

1
@Jose_GD ประเด็นก็คือมีกรณีการใช้งานจริงในชีวิตจริงซึ่งแนวทางของคุณจะถูกพิจารณาว่าเป็นจุดบกพร่อง หากคุณพบสิ่งหนึ่งอาจมีมากกว่านั้น ... ฉันไม่รู้ว่า Joda จัดการกับสิ่งนี้ได้อย่างไร แต่คุณสามารถดูได้ นอกจากนี้โปรดทราบว่า Java 8 นำเสนอไลบรารีวันที่ใหม่ (ตามประสบการณ์ของ Joda) ซึ่งคุณอาจต้องการพิจารณา
Thorbjørn Ravn Andersen

4

ไม่ใช่วิธีที่ถูกต้องที่สุด แต่ถ้าคุณต้องการโซลูชันที่รวดเร็วเพื่อรับวันที่ไม่มีเวลาและคุณไม่ต้องการใช้ห้องสมุดบุคคลที่สามสิ่งนี้ควรทำ

    Date db = db.substring(0, 10) + db.substring(23,28);

ฉันต้องการวันที่เพื่อจุดประสงค์ในการมองเห็นเท่านั้นและไม่สามารถ Joda ได้ดังนั้นฉันจึงซับสตริง


4
// 09/28/2015
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime()));

// Mon Sep 28
System.out.println( new Date().toString().substring(0, 10) );

// 2015-09-28
System.out.println(new java.sql.Date(System.currentTimeMillis()));

// 2015-09-28
// java 8
System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class

3

เท่าที่ฉันรู้ว่าไม่มีวิธีที่ง่ายกว่าที่จะบรรลุเป้าหมายนี้หากคุณใช้มาตรฐาน JDK เท่านั้น

แน่นอนคุณสามารถใส่ตรรกะนั้นใน method2 ลงในฟังก์ชั่นแบบคงที่ในคลาสผู้ช่วยเหมือนที่นี่ใน toBeginningOfTheDay-method

จากนั้นคุณสามารถย่อวิธีที่สองให้สั้นลงเพื่อ:

Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();

หรือถ้าคุณต้องการวันที่ปัจจุบันในรูปแบบนี้บ่อยมากคุณก็สามารถสรุปได้ด้วยวิธีการช่วยเหลือแบบคงที่อีกวิธีหนึ่งซึ่งทำให้เป็นแบบเส้นเดียว


3

หากสิ่งที่คุณต้องการที่จะเห็นวันที่เช่นดังนั้น "YYYY-MM-DD" โดยไม่ต้องทั้งหมดยุ่งเหยิงอื่น ๆ เช่น "พฤหัสบดีที่ 21 พฤษภาคม 2015 12:08:18 EDT" java.sql.Dateแล้วเพียงแค่ใช้ ตัวอย่างนี้รับวันที่ปัจจุบัน:

new java.sql.Date(System.currentTimeMillis());

นอกจากนี้ยังjava.sql.Dateเป็น subclass java.util.Dateของ


3

หากคุณต้องการวันที่ปัจจุบันโดยไม่มีเวลาตัวเลือกอื่นคือ:

DateTime.now().withTimeAtStartOfDay()

1
คำถามที่ถามไม่มีเวลาในวันนี้ ผลลัพธ์ของคุณคือวัตถุวันที่ซึ่งมีช่วงเวลาของวันเวลานั้นเป็น00:00:00ปกติ (อาจแตกต่างกันไปตามโซนเวลาสำหรับความผิดปกติเช่นDST ) ดังนั้นตามที่ทราบคำตอบอื่น ๆLocalDateชั้นเรียนมีความเหมาะสมมากกว่าจาก Joda-Time (สมมติว่าคุณกำลังอ้างอิง Joda-Time - ซึ่งคุณควรสังเกตอย่างชัดเจนเมื่ออ้างถึงคลาสที่ไม่ได้รวมกับ Java)
Basil Bourque

3

ใช้LocalDate.now()และแปลงเป็นDateดังนี้:

Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());

1
เขตเวลาเริ่มต้นปัจจุบันของ JVM สามารถเปลี่ยนแปลงได้ตลอดเวลาระหว่างรันไทม์ รหัสใด ๆ ในเธรดของแอพใด ๆ ภายใน JVM สามารถโทรTimeZone.setDefaultได้ รหัสของคุณจะเรียกZoneId.systemDefaultสองครั้งแรกคือนัยในและสองคืออย่างชัดเจนด้วยLocalDate.now() atStartOfDayในระหว่างช่วงเวลาสองช่วงเวลาขณะรันไทม์โซนเริ่มต้นปัจจุบันสามารถเปลี่ยนแปลงได้ ฉันขอแนะนำให้จับโซนเป็นตัวแปรและส่งผ่านไปยังทั้งสองวิธี
Basil Bourque

2

หากคุณต้องการส่วนวันที่เพียงเพื่อวัตถุประสงค์ในการสะท้อนแล้ว

Date d = new Date(); 
String dateWithoutTime = d.toString().substring(0, 10);

1
ฉันไม่คิดว่านี่เป็นมิตรกับ i18n
Mark Lapasa

2

แล้วเรื่องนี้ล่ะ

public static Date formatStrictDate(int year, int month, int dayOfMonth) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month, dayOfMonth, 0, 0, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}

1

ตรวจสอบVeyder เวลา มันเป็นทางเลือกที่ง่ายและมีประสิทธิภาพทั้ง java.util และ Joda-time มันมี API ที่ใช้งานง่ายและคลาสที่แสดงวันที่เพียงอย่างเดียวโดยไม่มีการประทับเวลา


1

วิธีที่ตรงไปตรงมาที่สุดที่ใช้ประโยชน์เต็มที่จากฐานข้อมูล TimeZone ขนาดใหญ่ของ Java และถูกต้อง:

long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);

1

นี่คือโซลูชันที่สะอาดโดยไม่มีการแปลงเป็นสตริงและย้อนกลับและยังไม่คำนวณเวลาใหม่หลายครั้งเมื่อคุณรีเซ็ตแต่ละองค์ประกอบของเวลาให้เป็นศูนย์ นอกจากนี้ยังใช้%(โมดูลัส) แทนการหารตามด้วยทวีคูณเพื่อหลีกเลี่ยงการทำงานสองครั้ง

มันไม่จำเป็นต้องพึ่งพาบุคคลที่สามและจะตอบสนองต่อเวลาของวัตถุ Calender ผ่านเข้ามาฟังก์ชั่นนี้จะส่งกลับช่วงเวลาในเวลา 12.00 นในเขตเวลาของวันที่ (ปฏิทิน) ที่คุณผ่าน

public static Calendar date_only(Calendar datetime) {
    final long LENGTH_OF_DAY = 24*60*60*1000;
    long millis = datetime.getTimeInMillis();
    long offset = datetime.getTimeZone().getOffset(millis);
    millis = millis - ((millis + offset) % LENGTH_OF_DAY);
    datetime.setTimeInMillis(millis);
    return datetime;
}

ฉันไม่มั่นใจว่ามันจะเคารพ Summer Tme (DST) หรือไม่
Ole VV

0

ไม่ต้องการใช้ไลบรารีบุคคลที่สามมากที่สุด ฉันรู้ว่าวิธีนี้ถูกกล่าวถึงก่อนหน้านี้ แต่นี่เป็นวิธีที่สะอาดดี

  /*
    Return values:
    -1:    Date1 < Date2
     0:    Date1 == Date2
     1:    Date1 > Date2

    -2:    Error
*/
public int compareDates(Date date1, Date date2)
{
    SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

    try
    {
        date1 = sdf.parse(sdf.format(date1));
        date2 = sdf.parse(sdf.format(date2));
    }
    catch (ParseException e) {
        e.printStackTrace();
        return -2;
    }

    Calendar cal1 = new GregorianCalendar();
    Calendar cal2 = new GregorianCalendar();

    cal1.setTime(date1);
    cal2.setTime(date2);

    if(cal1.equals(cal2))
    {
        return 0;
    }
    else if(cal1.after(cal2))
    {
        return 1;
    }
    else if(cal1.before(cal2))
    {
        return -1;
    }

    return -2;
}

การไม่ใช้ GregorianCalendar อาจเป็นตัวเลือก!


0

ฉันเพิ่งทำสิ่งนี้เพื่อแอพของฉัน:

public static Date getDatePart(Date dateTime) {
    TimeZone tz = TimeZone.getDefault();
    long rawOffset=tz.getRawOffset();
    long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0);
    long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime
    long modDt=dt % (60*60*24*1000) ;

    return new Date( dt
                    - modDt // substract the rest of the division by a day in milliseconds
                    - rawOffset // substract the time offset (Paris = GMT +1h for example)
                    - dst // If dayLight, substract hours (Paris = +1h in dayLight)
    );
}

Android API ระดับ 1 ไม่มีไลบรารีภายนอก มันเคารพเวลากลางวันและเขตเวลาเริ่มต้น ไม่มีการจัดการสตริงดังนั้นฉันคิดว่าวิธีนี้มีประสิทธิภาพของ CPU มากกว่าของคุณ แต่ฉันไม่ได้ทำการทดสอบใด ๆ


0

Yo สามารถใช้เวลา joda ได้

private Date dateWitoutTime(Date date){
 return new LocalDate(date).toDate()
}

และคุณโทรด้วย:

Date date = new Date();
System.out.println("Without Time = " + dateWitoutTime(date) + "/n  With time = " + date);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.