Làm thế nào để tạo một đối tượng Ngày Java của nửa đêm hôm nay và nửa đêm ngày mai?


178

Trong mã của tôi, tôi cần tìm tất cả những điều đã xảy ra hôm nay. Vì vậy, tôi cần so sánh với các ngày từ hôm nay lúc 00:00 sáng (nửa đêm sớm sáng nay) đến 12:00 tối (nửa đêm tối nay).

Tôi biết ...

Date today = new Date(); 

... có được tôi ngay bây giờ. Và ...

Date beginning = new Date(0);

... giúp tôi có thời gian bằng không vào ngày 1 tháng 1 năm 1970. Nhưng cách dễ dàng để có thời gian bằng không hôm nay và không có thời gian vào ngày mai là gì?

CẬP NHẬT; Tôi đã làm điều này, nhưng chắc chắn có một cách dễ dàng hơn?

Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();

Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();

3
Theo tôi Joda Time dễ dàng hơn, hãy nhìn vào cuối câu trả lời của tôi. Nếu bạn muốn sử dụng java.util.Date/CalWiki, bạn phải làm theo cách này, không có cách nào dễ dàng hơn để làm điều đó.
timaschew

RE: timaschew bình luận để sử dụng Joda-Time, biết rằng dự án Joda-Time hiện đang ở chế độ bảo trì và khuyên chuyển sang các lớp java.time.
Basil Bourque

1
FYI, người già lớp ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

2
Rất hiếm khi thấy nhiều câu trả lời thiếu sót cho câu hỏi này. Tôi đề nghị câu trả lời của Basil Bourque , nó là chính xác và hiểu biết.
Ole VV

Câu trả lời:


344

java.util.CalWiki

// today    
Calendar date = new GregorianCalendar();
// reset hour, minutes, seconds and millis
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);

// next day
date.add(Calendar.DAY_OF_MONTH, 1);

JDK 8 - java.time.LocalTime và java.time.LocalDate

LocalTime midnight = LocalTime.MIDNIGHT;
LocalDate today = LocalDate.now(ZoneId.of("Europe/Berlin"));
LocalDateTime todayMidnight = LocalDateTime.of(today, midnight);
LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1);

Joda-Thời gian

Nếu bạn đang sử dụng JDK <8, tôi khuyên dùng Joda Time , vì API thực sự rất hay:

DateTime date = new DateTime().toDateMidnight().toDateTime();
DateTime tomorrow = date.plusDays(1);

Kể từ phiên bản 2.3 của Joda Thời gian DateMidnightđược phản , vì vậy sử dụng này:

DateTime today = new DateTime().withTimeAtStartOfDay();
DateTime tomorrow = today.plusDays(1).withTimeAtStartOfDay();

Vượt qua múi giờ nếu bạn không muốn múi giờ mặc định hiện tại của JVM.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.

Cảm ơn sự giúp đỡ, tôi vừa cập nhật câu hỏi ban đầu của mình với cách mà tôi hiện đang làm nó. Cám ơn vì sự gợi ý.

3
Kể từ JodaTime 2.3, toDateMidnightkhông được chấp nhận. Xem câu trả lời này để biết chi tiết: stackoverflow.com/a/19048833/363573
Stephan

đã thêm một giải pháp cho JDK 8
timaschew

1
@timaschew Mặc dù nói chung là chính xác, tôi khuyên bạn nên thực hiện java.time bằng cách sử dụng giá trị thời gian ngày được khoanh vùng ( ZonedDateTime) như bạn đã làm trong phần Joda-Time. Các Local…loại không có thông tin múi giờ - đó là toàn bộ mục đích của chúng, không mất / bỏ qua tất cả các chi tiết bù và múi giờ. Đặc biệt là khi Câu hỏi nói về việc sử dụng các giá trị này để so sánh (có thể là truy vấn cơ sở dữ liệu?), Giá trị thời gian ngày được khoanh vùng có thể sẽ hữu ích hơn.
Basil Bourque

1
@Amalgovinus Đảm bảo đặt Lịch.HOUR_OF_DAY, không phải Lịch.HOUR.
Oswald

43

Để hoàn thiện, nếu bạn đang sử dụng Java 8, bạn cũng có thể sử dụng truncatedTophương thức của Instantlớp để có được nửa đêm trong UTC .

Instant.now().truncatedTo(ChronoUnit.DAYS);

Như được viết trong Javadoc

Ví dụ: cắt ngắn với đơn vị MINUTES sẽ làm tròn đến phút gần nhất, đặt giây và nano giây về 0.

Hy vọng nó giúp.


1
Cảm ơn đã gợi ý. Bắt nửa đêm ở múi giờ quy định trở nên dài hơn:Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
Vadzim


33

Cách dễ nhất để tìm một nửa đêm:

Long time = new Date().getTime();
Date date = new Date(time - time % (24 * 60 * 60 * 1000));

Ngày tiếp theo:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);

Tôi đã chạy mã đó và nhận được: Nửa đêm: Ngày 01 tháng 11 19:00:00 CDT 2012
Dave

3
Nếu bạn đã làm một cái gì đó như System.out.print (ngày), hệ thống sẽ chuyển đổi thể hiện ngày thành múi giờ hệ thống (CDT). 7 giờ tối trong CDT là nửa đêm trong GMT. Nếu bạn cần nửa đêm trong múi giờ đã chọn, bạn phải thêm phần bù của múi giờ này, tính đến DST.
Andrei Volgin

@Bouncner Đó là. Có nhiều thời gian 'nửa đêm' khác nhau trên Trái đất bất kể bạn sử dụng phương pháp nào, nhưng chỉ có một nửa đêm Java.
Andrei Volgin

2
@Andrei Volgin Không biết rằng có "java nửa đêm". ;) Điều tôi muốn nói là giải pháp này không thực sự giúp ích cho người tạo chủ đề. Một giải pháp lịch tránh các tính toán thứ hai xấu xí và chăm sóc các múi giờ (và đặc biệt là thời gian tiết kiệm ánh sáng ban ngày, v.v.) khi được sử dụng đúng cách. Tôi không thấy điều đó trong giải pháp của bạn.
Bouncner

Xin chào @AndreiVolgin, tôi đã nhận được với Date date = new Date (time + TimeZone.getDefault (). GetRaw Offerset () - time% (24 * 60 * 60 * 1000));
jrey

28

Hãy nhớ rằng, Datekhông được sử dụng để đại diện cho ngày (!). Để đại diện cho ngày bạn cần một lịch. Điều này:

Calendar c = new GregorianCalendar();

sẽ tạo một Calendarthể hiện đại diện cho ngày hiện tại trong múi giờ hiện tại của bạn. Bây giờ những gì bạn cần là cắt ngắn mọi trường bên dưới ngày (giờ, phút, giây và mili giây) bằng cách đặt nó thành 0. Bây giờ bạn có một nửa đêm ngày hôm nay.

Bây giờ để có được nửa đêm ngày hôm sau, bạn cần thêm một ngày:

c.add(Calendar.DAY_OF_MONTH, 1);

Lưu ý rằng việc thêm 86400giây hoặc 24 giờ là không chính xác do thời gian mùa hè có thể xảy ra trong thời gian đó.

CẬP NHẬT: Tuy nhiên cách yêu thích của tôi để giải quyết vấn đề này là sử dụng lớp DateUtils từ Commons Lang :

Date start = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH))
Date end = DateUtils.addDays(start, 1);

Nó sử dụng Calendarđằng sau hậu trường ...


15
Cảm ơn đã giúp đỡ. "Ngày không được sử dụng để đại diện cho ngày" - chúng ta sẽ rất tuyệt vời phải không? ;)

@RobertHume Công bằng mà nói, Date đã xuất hiện kể từ lần phát hành Java đầu tiên. Hầu hết mọi thứ từ thời đại đó là ... ít hơn hoàn toàn nghĩ ra. Đặc biệt là vì Java là một trong những người đầu tiên thử các loại mà nó đang thử và còn lâu mới đạt được tiêu chuẩn đã được thống nhất về cách thực hiện.
Vụ kiện của Quỹ Monica

14

những phương pháp này sẽ giúp bạn-

public static Date getStartOfDay(Date date) {
     Calendar calendar = Calendar.getInstance();
     calendar.setTime(date);
     calendar.set(Calendar.HOUR_OF_DAY, 0);
     calendar.set(Calendar.MINUTE, 0);
     calendar.set(Calendar.SECOND, 0);
     calendar.set(Calendar.MILLISECOND, 0);
     return calendar.getTime();
 }

public static Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
}

9

Kể từ JodaTime 2.3, toDateMidnight() không được chấp nhận.

Từ nâng cấp từ 2.2 lên 2.3

    Khấu hao kể từ 2.2
    ----------------------
    - Ngày nghỉ đêm [# 41]
     Lớp học này là thiếu sót trong khái niệm
     Thời gian nửa đêm thỉnh thoảng không xảy ra ở một số múi giờ
     Đây là kết quả của thời gian tiết kiệm ánh sáng ban ngày từ 00:00 đến 01:00
     DateUnnight thực chất là một DateTime với thời gian bị khóa đến nửa đêm
     Một khái niệm như vậy nói chung là một khái niệm kém để sử dụng, được đưa ra LocalDate
     Thay thế ngày nghỉ đêm bằng LocalDate
     Hoặc thay thế nó bằng DateTime, có thể sử dụng phương thức withTimeAtStartOfDay ()

Đây là một mã mẫu không có toDateMidnight()phương pháp.

DateTime todayAtMidnight = new DateTime().withTimeAtStartOfDay();
System.out.println(todayAtMidnight.toString("yyyy-MM-dd HH:mm:ss"));

Đầu ra ( có thể khác nhau tùy theo múi giờ địa phương của bạn )

2013-09-28 00:00:00

2
Câu trả lời tuyệt vời. Tôi sẽ bổ sung việc chuyển một DateTimeZonethể hiện cho nhà DateTimexây dựng đó để nhấn mạnh tầm quan trọng của việc chỉ định múi giờ thay vì vô tình tùy thuộc vào mặc định:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
Basil Bourque

9

Các câu trả lời khác là chính xác, đặc biệt là câu trả lời java.time của arganzheng . Như một số đề cập, bạn nên tránh các lớp java.util.Date/.CalWiki cũ vì chúng được thiết kế kém, khó hiểu và rắc rối. Chúng đã được thay thế bởi các lớp java.time.

Hãy để tôi thêm ghi chú về chiến lược xung quanh việc xử lý nửa đêmkhoảng thời gian .

Mở một nửa

Trong công việc thời gian, các khoảng thời gian thường được xác định bằng cách sử dụng phương pháp tiếp cận Half Half Open. Trong cách tiếp cận này, sự khởi đầu là bao gồm trong khi kết thúc là độc quyền . Điều này giải quyết vấn đề và nếu được sử dụng một cách nhất quán làm cho lý do về việc xử lý thời gian ngày của bạn dễ dàng hơn nhiều.

Một vấn đề được giải quyết là xác định cuối ngày. Là khoảnh khắc cuối cùng trong ngày 23:59:59.999( mili giây )? Có lẽ, trong lớp java.util.Date (từ Java sớm nhất; rắc rối - tránh lớp này!) Và trong thư viện Joda-Time rất thành công . Nhưng trong các phần mềm khác, chẳng hạn như cơ sở dữ liệu như Postgres, khoảnh khắc cuối cùng sẽ là 23:59:59.999999( micro giây ). Nhưng trong các phần mềm khác như khung java.time (được tích hợp vào Java 8 trở lên, kế thừa Joda-Time) và trong một số cơ sở dữ liệu như Cơ sở dữ liệu H2 , khoảnh khắc cuối cùng có thể là 23:59.59.999999999( nano giây ). Thay vì chia tóc, hãy nghĩ về khoảnh khắc đầu tiên, không phải khoảnh khắc cuối cùng.

Trong Half-Open, một ngày chạy từ khoảnh khắc đầu tiên của một ngày và đi lên nhưng không bao gồm khoảnh khắc đầu tiên của ngày tiếp theo. Vì vậy, thay vì nghĩ như thế này:

Từ hôm nay lúc 00:00 sáng (nửa đêm sáng sớm) đến 12:00 tối (nửa đêm nay).

Hãy nghĩ như thế này

từ khoảnh khắc đầu tiên của ngày hôm nay chạy đến nhưng không bao gồm khoảnh khắc đầu tiên của ngày mai:
(> = 00:00:00.0hôm nay VÀ < 00:00:00.0ngày mai)

Trong công việc cơ sở dữ liệu, cách tiếp cận này có nghĩa là không sử dụng BETWEENtoán tử trong SQL.

Ngày bắt đầu

Hơn nữa, khoảnh khắc đầu tiên trong ngày không phải lúc nào cũng là thời gian trong ngày 00:00:00.0. Thời gian tiết kiệm ánh sáng ban ngày (DST) ở một số múi giờ, và có thể là sự bất thường khác, có thể có nghĩa là một thời gian khác nhau bắt đầu một ngày.

Vì vậy, hãy để các lớp java.time thực hiện công việc xác định bắt đầu một ngày bằng một cuộc gọi đến LocalDate::atStartOfDay( ZoneId ). Vì vậy, chúng ta phải đi vòng qua LocalDatevà quay lại ZonedDateTimenhư bạn có thể thấy trong mã ví dụ này.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );

Lưu ý việc vượt qua tùy chọn ZoneId. Nếu bỏ qua múi giờ mặc định hiện tại của JVM của bạn sẽ được áp dụng hoàn toàn. Tốt hơn để được rõ ràng.

Múi giờ là rất quan trọng để làm việc thời gian. Câu hỏi và một số câu trả lời khác có khả năng thiếu sót vì không có ý thức xử lý múi giờ.

Đổi

Nếu bạn phải sử dụng java.util.Date hoặc .CalWiki, hãy tìm các phương thức chuyển đổi mới được thêm vào các lớp cũ đó.

java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );

Khoảng thời gian

Nhân tiện, nếu bạn đang làm nhiều việc với khoảng thời gian, hãy xem:

  • Duration
  • Period
  • Interval
    Các Intervallớp học được tìm thấy trong ThreeTen-Extra dự án, một mở rộng của khuôn khổ java.time. Dự án này là nền tảng chứng minh cho những bổ sung có thể có trong tương lai cho java.time.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

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?

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 .


6

java.time

Nếu bạn đang sử dụng Java 8 trở lên, bạn có thể thử gói java.time ( Hướng dẫn ):

LocalDate tomorrow = LocalDate.now().plusDays(1);
Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant());

2
Câu trả lời tốt. Tôi sẽ đề nghị chỉ định múi giờ mong muốn / dự kiến. Múi giờ mặc định hiện tại của JVM có thể thay đổi tùy theo cài đặt HĐH, thay đổi máy tính hoặc bất kỳ ứng dụng nào trong bất kỳ luồng nào của JVM thay đổi mặc định bất cứ lúc nào trong thời gian chạy.
Basil Bourque

4

Điều này dường như là một lựa chọn:

DateFormat justDay = new SimpleDateFormat("yyyyMMdd");
Date thisMorningMidnight = justDay.parse(justDay.format(new Date()));

để thêm một ngày cho nó

Date tomorrow = new Date(thisMorningMidnight.getTime() + 24 * 60 * 60 * 1000);

hoặc là

Calendar c = Calendar.getInstance();
c.setTime(thisMorningMidnight);
c.add(Calendar.DATE, 1);
Date tomorrowFromCalendar = c.getTime();

Tôi có linh cảm thứ hai được ưa thích trong trường hợp có thứ gì đó kỳ lạ như tiết kiệm ánh sáng ban ngày khiến việc thêm 24 giờ là không đủ (xem https://stackoverflow.com/a/4336131/32453 và các câu trả lời khác của nó).


Tôi có một ngày và thời gian trong ngày được thể hiện dưới dạng dài trong cơ sở dữ liệu sqlite của tôi. Tôi cần phải có được một thời gian dài cho đầu ngày hôm sau. Tôi vẫn có thể sử dụng một đối tượng Date với thời gian dài hơn là với phương thức SimpleDateFormat mà bạn sử dụng ở trên chứ?
AJW

1
Miễn là đúng mili giây, bạn có thể vượt qua nó như một công cụ xây dựng: docs.oracle.com/javase/7/docs/api/java/util/iêu
rogerdpack 18/10/18

1

Tôi đã làm điều này khác với những người khác ở đây đã làm. Tôi mới sử dụng Java, vì vậy có lẽ giải pháp của tôi rất kém.

Date now = new Date();
Date midnightToday = new Date(now.getYear(), now.getMonth(), now.getDate());

Tôi không chắc điều này có hiệu quả chưa, nhưng dù sao đi nữa, tôi đánh giá cao bất kỳ phản hồi nào về giải pháp này.

Tôi bối rối trước câu nói trên mà bạn có thể tính toán vào ngày mai bằng cách gọi:

c.add(Calendar.DAY_OF_MONTH, 1);

Nếu bạn thêm 1 vào ngày trong tháng và đó là ngày thứ 31, bạn không có ngày thứ 32 trong tháng phải không?

Tại sao thời gian / ngày không phải tất cả dựa trên UTC trong Java? Tôi nghĩ rằng chỉ nên sử dụng Timezones khi được sử dụng với i / o, nhưng bên trong luôn phải được sử dụng trong UTC. Tuy nhiên, các lớp dường như bao gồm thông tin Timezone dường như không chỉ lãng phí mà còn dễ bị lỗi mã hóa.


2
Xin chào Mitch. Tôi nghĩ rằng giải pháp của bạn hoạt động, nhưng có vẻ như hàm tạo ngày đó không được dùng nữa. Mọi người Java đã từ chối hầu hết các phương thức liên quan đến Ngày ban đầu một thời gian trước và thay thế chúng bằng các phương thức liên quan đến Lịch mới hơn. Cá nhân tôi không thấy đó là một cải tiến, nhưng nó cau mày khi sử dụng các phương pháp không dùng nữa. Cảm ơn!

Buồn về sự mất giá. Nó có vẻ sạch sẽ hơn nhiều đối với tôi để chỉ định năm, tháng và ngày thay vì xóa giờ, phút, giây và millisecs. Việc xóa những thứ này phụ thuộc vào millisec là độ chi tiết tốt nhất của lớp Date, trong khi giải pháp của tôi thì không. Giải pháp của tôi cũng ngắn hơn và rõ ràng hơn. Việc mới làm quen với Java khiến tôi thực sự đánh giá cao C ++ sạch sẽ, dễ dàng và hiệu quả như thế nào khi sử dụng ngày và giờ.
Mitch

@Mitch Theo kinh nghiệm của tôi, ngôn ngữ gần đây nhất mà bạn đang học luôn được coi là phức tạp nhất.
ArtOfWarfare

FYI: các lớp thời gian cũ khủng khiếp đẫm máu này hiện đang là di sản, được thay thế bởi các lớp java.time hiện đại.
Basil Bourque


0

Cách đơn giản nhất với JodaTime

DateMidnight date = DateMidnight.now();


2
Không. Các lớp học và phương pháp liên quan đến "nửa đêm" trong Joda-Time đều bị phản đối. Họ đã dựa trên một khái niệm thiếu sót. Khoảnh khắc đầu tiên trong ngày không phải lúc nào cũng vậy 00:00:00.000. Thay vào đó sử dụng withTimeAtStartOfDayphương pháp mới . Cập nhật lên phiên bản 2.4 hiện tại của Joda-Time và đọc ghi chú phát hành. Ví dụ:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Basil Bourque

0

Bởi vì một ngày là 24 * 60 * 60 * 1000ms, nửa đêm của ngày này có thể được tính là ...

long now = System.currentTimeMillis();
long delta = now % 24 * 60 * 60 * 1000;
long midnight = now - delta;
Date midnightDate = new Date(midnight);`

1
Mã này chỉ áp dụng cho UTC và không có múi giờ khác và bỏ qua các bất thường như Giờ tiết kiệm ánh sáng ban ngày. Hơn nữa, các giải pháp thời gian ngày của riêng bạn là không khôn ngoan vì đây là một chủ đề khó khăn đáng ngạc nhiên. Sử dụng các lớp java.time tuyệt vời thay thế.
Basil Bourque

0

Khá nhiều câu trả lời trước đây, nhưng không ai đề cập đến tham số AM_PM:

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    cal.set(Calendar.AM_PM, Calendar.AM);

1
Lớp rắc rối Calendarđã được thay thế từ nhiều năm trước bởi các lớp java.time , đặc biệt ZonedDateTime.
Basil Bourque

0
Date now= new Date();
// Today midnight
Date todayMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY);

// tomorrow midnight
Date tomorrowMidnight = new Date(endTime.getTime() -endTime.getTime()%DateUtils.MILLIS_PER_DAY + DateUtils.MILLIS_PER_DAY);

Điều này chỉ hoạt động cho UTC và không giải quyết được múi giờ. Ngoài ra, Datelớp học khủng khiếp đã được thay thế từ nhiều năm trước java.time.Instant. Tránh sử dụng Datengày nay.
Basil Bourque

0

Sử dụng chung apache ..

//For midnight today 
Date today = new Date(); 
DateUtils.truncate(today, Calendar.DATE);

//For midnight tomorrow   
Date tomorrow = DateUtils.addDays(today, 1); 
DateUtils.truncate(tomorrow, Calendar.DATE);

FYI, người già lớp ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

@BasilBourque Đồng ý cho Java 8. Nhưng nếu OP đang sử dụng Java 7, tôi đoán vẫn sẽ hoạt động.
joe4java

Gần như tất cả các chức năng java.time có sẵn cho Java 6 & 7 trong dự án ThreeTen-Backport với API gần như giống hệt nhau. Thích nghi hơn nữa cho Android <26 trong dự án ThreeTenABP . Vì vậy, không cần phải sử dụng lại các lớp ngày giờ cũ khốn khổ đó.
Basil Bourque

-1

Tôi biết đây là bài viết rất cũ. Tôi nghĩ để chia sẻ kiến ​​thức của tôi ở đây!

Đối với ngày Giữa đêm hôm nay với Múi giờ chính xác, bạn có thể sử dụng như sau

public static Date getCurrentDateWithMidnightTS(){

    return new Date(System.currentTimeMillis() - (System.currentTimeMillis()%(1000*60*60*24)) - (1000*60 * 330));
}

Ở đâu (1000*60 * 330) đang bị trừ tức là thực sự liên quan đến múi giờ, ví dụ múi giờ Ấn Độ, tức là kolkata khác +5: 30 giờ so với thực tế. Vì vậy, trừ đi với việc chuyển đổi thành mili giây.

Vì vậy, thay đổi số trừ cuối cùng theo bạn. Tôi đang tạo ra một sản phẩm tức là chỉ có trụ sở tại Ấn Độ. Vì vậy, chỉ sử dụng dấu thời gian cụ thể.


1
Tại sao bạn lại đề nghị điều này thay vì câu trả lời được chấp nhận? Nói chung, giá trị thời gian của bạn rất rủi ro. Cụ thể, mã này được mã hóa cứng thành phần bù hiện tại của một múi giờ duy nhất. Không có kế toán cho Giờ tiết kiệm ánh sáng ban ngày hoặc các bất thường khác. Tôi chỉ thấy nhược điểm không có giá trị gia tăng.
Basil Bourque

@Basil tất nhiên tôi chấp nhận câu trả lời và vâng tôi đã đề cập ở đó cho giá trị mã hóa cứng. Điều này chỉ hữu ích trong trường hợp bạn đang làm việc trên một múi giờ cụ thể.
Rajeev

-1
Date todayMidnightUTC = java.sql.Date.valueOf(LocalDate.now());
Date tomorrowMidnightUTC = java.sql.Date.valueOf(LocalDate.now().plusDays(1));
Date anyMidnightLocal = java.sql.Date.valueOf(LocalDate.from(dateTime.toInstant().atZone(ZoneId.systemDefault())));

Nhưng hãy cẩn thận mà java.sql.Date.toInstant()luôn ném UnsupportedOperationException.

Qua LocalDate sang java.util.Date và ngược lại chuyển đổi đơn giản nhất?


Không phải là một câu trả lời tốt. Bạn đang trộn lẫn việc sử dụng java.time hiện đại với các lớp kế thừa cũ mà chúng thay thế. Và cụ thể là bạn sử dụng các lớp thời gian ngày java.sql chỉ nên được sử dụng để trao đổi dữ liệu với cơ sở dữ liệu mà trình điều khiển chưa được cập nhật để xử lý trực tiếp với các lớp java.time, không bao giờ được sử dụng cho logic nghiệp vụ. Một vấn đề khác là bạn bỏ qua vấn đề cốt yếu của múi giờ.
Basil Bourque

@BasilBourque, cảm ơn bạn đã phê bình. Sử dụng một lớp kế thừa không được đánh dấu là không dùng nữa để có được một thể hiện của lớp kế thừa khác là khá an toàn. Vấn đề múi giờ là quan trọng hơn. Rốt cuộc, tôi quyết định gắn bó với câu trả lời của riccardo .
Vadzim

-1

Cách cũ ..

private static Date getDateWithMidnight(){
    long dateInMillis = new Date().getTime();
    return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis));
}

Lớp rắc rối đó đã được lớp java.time.Instant thay thế nhiều năm trước . Không cần phải sử dụng Date.
Basil Bourque

DateLớp học đó luôn ở trong UTC. Vì vậy, bạn đang bỏ qua vấn đề về múi giờ mong muốn / mong đợi. Ví dụ, một ngày mới khởi đầu ở Kolkata Ấn Độ sớm hơn nhiều giờ so với ở UTC và muộn hơn UTC ở Montréal Québec vài giờ.
Basil Bourque
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.