152

如何获取一天的开始时间和结束时间?

像这样的代码不准确:

 private Date getStartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.set(year, month, day, 0, 0, 0);
    return calendar.getTime();
}

private Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.set(year, month, day, 23, 59, 59);
    return calendar.getTime();
}

它不精确到毫秒。

4

18 回答 18

198

爪哇 8


public static Date atStartOfDay(Date date) {
    LocalDateTime localDateTime = dateToLocalDateTime(date);
    LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
    return localDateTimeToDate(startOfDay);
}

public static Date atEndOfDay(Date date) {
    LocalDateTime localDateTime = dateToLocalDateTime(date);
    LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
    return localDateTimeToDate(endOfDay);
}

private static LocalDateTime dateToLocalDateTime(Date date) {
    return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}

private static Date localDateTimeToDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}

更新:我已将这两种方法添加到我的 Java 实用程序类

它位于 Maven 中央存储库中:

<dependency>
  <groupId>com.github.rkumsher</groupId>
  <artifactId>utils</artifactId>
  <version>1.3</version>
</dependency>

Java 7 及更早版本


使用 Apache Commons

public static Date atEndOfDay(Date date) {
    return DateUtils.addMilliseconds(DateUtils.ceiling(date, Calendar.DATE), -1);
}

public static Date atStartOfDay(Date date) {
    return DateUtils.truncate(date, Calendar.DATE);
}

没有 Apache Commons

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

public Date atStartOfDay(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();
}
于 2012-10-01T19:09:46.897 回答
159
于 2013-12-12T05:54:12.993 回答
29

在 getEndOfDay 中,您可以添加:

calendar.set(Calendar.MILLISECOND, 999);

虽然从数学上讲,你不能指定一天的结束,只能说它是“在第二天开始之前”。

所以不要说if(date >= getStartOfDay(today) && date <= getEndOfDay(today)),,你应该说:if(date >= getStartOfDay(today) && date < getStartOfDay(tomorrow))。这是一个更可靠的定义(您不必担心毫秒精度)。

于 2012-04-25T02:05:01.060 回答
19

java.time

使用java.timeJava 8 内置的框架。

import java.time.LocalTime;
import java.time.LocalDateTime;

LocalDateTime now = LocalDateTime.now(); // 2015-11-19T19:42:19.224
// start of a day
now.with(LocalTime.MIN); // 2015-11-19T00:00
now.with(LocalTime.MIDNIGHT); // 2015-11-19T00:00
// end of a day
now.with(LocalTime.MAX); // 2015-11-19T23:59:59.999999999
于 2015-11-19T18:48:38.497 回答
5

Java 8 或 ThreeTenABP

分区日期时间

ZonedDateTime curDate = ZonedDateTime.now();

public ZonedDateTime startOfDay() {
    return curDate
    .toLocalDate()
    .atStartOfDay()
    .atZone(curDate.getZone())
    .withEarlierOffsetAtOverlap();
}

public ZonedDateTime endOfDay() {

    ZonedDateTime startOfTomorrow =
        curDate
        .toLocalDate()
        .plusDays(1)
        .atStartOfDay()
        .atZone(curDate.getZone())
        .withEarlierOffsetAtOverlap();

    return startOfTomorrow.minusSeconds(1);
}

// based on https://stackoverflow.com/a/29145886/1658268

本地日期时间

LocalDateTime curDate = LocalDateTime.now();

public LocalDateTime startOfDay() {
    return curDate.atStartOfDay();
}

public LocalDateTime endOfDay() {
    return startOfTomorrow.atTime(LocalTime.MAX);  //23:59:59.999999999;
}

// based on https://stackoverflow.com/a/36408726/1658268

我希望这对某人有所帮助。

于 2018-05-17T20:51:30.227 回答
4

使用 java8 java.time.ZonedDateTime 查找一天开始的另一种方法LocalDateTime是简单地将输入 ZonedDateTime 截断为 DAYS:

zonedDateTimeInstance.truncatedTo( ChronoUnit.DAYS );
于 2017-08-02T16:45:19.317 回答
2

另一种不依赖于任何框架的解决方案是:

static public Date getStartOfADay(Date day) {
    final long oneDayInMillis = 24 * 60 * 60 * 1000;
    return new Date(day.getTime() / oneDayInMillis * oneDayInMillis);
}

static public Date getEndOfADay(Date day) {
    final long oneDayInMillis = 24 * 60 * 60 * 1000;
    return new Date((day.getTime() / oneDayInMillis + 1) * oneDayInMillis - 1);
}

请注意,它返回基于 UTC 的时间

于 2018-01-31T14:31:09.700 回答
2

我知道这有点晚了,但在 Java 8 的情况下,如果您使用的是 OffsetDateTime(它提供了很多优势,例如 TimeZone、Nanoseconds 等),您可以使用以下代码:

OffsetDateTime reallyEndOfDay = someDay.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
// output: 2019-01-10T23:59:59.999999999Z
于 2019-08-30T19:59:43.723 回答
2

我试过这段代码,效果很好!

final ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
final ZonedDateTime startofDay =
    now.toLocalDate().atStartOfDay(ZoneOffset.UTC);
final ZonedDateTime endOfDay =
    now.toLocalDate().atTime(LocalTime.MAX).atZone(ZoneOffset.UTC);
于 2018-07-31T06:30:50.800 回答
2

对于 java 8,以下单行语句正在工作。在此示例中,我使用 UTC 时区。请考虑更改您当前使用的 TimeZone。

System.out.println(new Date());

final LocalDateTime endOfDay       = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
final Date          endOfDayAsDate = Date.from(endOfDay.toInstant(ZoneOffset.UTC));

System.out.println(endOfDayAsDate);

final LocalDateTime startOfDay       = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
final Date          startOfDayAsDate = Date.from(startOfDay.toInstant(ZoneOffset.UTC));

System.out.println(startOfDayAsDate);

如果与输出没有时间差。尝试:ZoneOffset.ofHours(0)

于 2017-07-14T16:23:58.940 回答
1

最短的答案,考虑到您的时区是TZ

LocalDateTime start = LocalDate.now(TZ).atStartOfDay()
LocalDateTime end = start.plusDays(1)

比较使用isAfter()和方法,或使用或方法isBefore()转换它。toEpochSecond()toInstant()

于 2021-02-26T17:16:01.837 回答
1
private Date getStartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.setTimeInMillis(0);
    calendar.set(year, month, day, 0, 0, 0);
    return calendar.getTime();
    }

private Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.setTimeInMillis(0);
    calendar.set(year, month, day, 23, 59, 59);
    return calendar.getTime();
    }

calendar.setTimeInMillis(0); 为您提供高达毫秒的精度

于 2020-01-31T09:35:11.230 回答
0

我认为最简单的方法是:

// Joda Time

DateTime dateTime=new DateTime(); 

StartOfDayMillis = dateTime.withMillis(System.currentTimeMillis()).withTimeAtStartOfDay().getMillis();
EndOfDayMillis = dateTime.withMillis(StartOfDayMillis).plusDays(1).minusSeconds(1).getMillis();

然后可以根据您的 Joda Time 要求将这些毫秒转换为日历、即时或本地日期。

于 2020-03-26T10:47:31.643 回答
0
 //this will work for user in time zone MST with 7 off set or UTC with saving time 

 //I have tried all the above and they fail the only solution is to use some math
 //the trick is to rely on $newdate is time()     //strtotime is corrupt it tries to read to many minds
 //convert to time to use with javascript*1000
 
 $dnol = strtotime('today')*1000;
 $dn = ($newdate*1000)-86400000;
 $dz=$dn/86400000;      //divide into days
 $dz=floor($dz);     //filter off excess time
 $dzt=$dz*86400000;     // put back into days UTC
 $jsDate=$dzt*1+(7*3600000);     // 7 is the off set you can store the 7 in database
 $dzt=$dzt-3600000;      //adjusment for summerTime UTC additional table for these dates will drive you crazy
 //solution get users [time off sets] with browser, up date to data base for user with ajax when they ain't lookin



 <?php
 $t=time();
 echo($t . "<br>");
 echo(date("Y-m-d",$t));
 echo '<BR>'.$dnol;
 echo '<BR>'.$dzt.'<BR>';
 echo(date("Y-m-d",$dzt/1000));      //convert back for php /1000
 echo '<BR>';
 echo(date('Y-m-d h:i:s',$dzt/1000));

 ?>
于 2021-01-23T03:31:15.093 回答
0

我对所有解决方案都有一些不便,因为我需要Instant变量的类型,而时区总是会干扰更改所有内容,然后结合解决方案我发现这是一个不错的选择。

        LocalDate today = LocalDate.now();
        Instant startDate = Instant.parse(today.toString()+"T00:00:00Z");
        Instant endDate = Instant.parse(today.toString()+"T23:59:59Z");

结果我们有

        startDate = 2020-01-30T00:00:00Z
        endDate = 2020-01-30T23:59:59Z

希望对你有帮助

于 2020-01-30T15:41:05.687 回答
0

以下代码采用 OP 的原始公式,并针对 ms 不精确性进行调整:

    private static Date getStartOfDay() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 0, 0, 0);
        long approximateTimestamp = calendar.getTime().getTime();
        long extraMillis = (approximateTimestamp % 1000);
        long exactTimestamp = approximateTimestamp - extraMillis;
        return new Date(exactTimestamp);
    }

    private static Date getEndOfDay() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 23, 59, 59);
        long approximateTimestamp = calendar.getTime().getTime();
        long extraMillis = (approximateTimestamp % 1000);
        long exactTimestamp = approximateTimestamp - extraMillis + 999;
        return new Date(exactTimestamp);
    }

与此线程上的许多其他答案不同,它与旧版本的 Java 和 Android API 兼容。

于 2021-01-30T14:55:34.840 回答
-2
Date date = new Date();
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);

时间戳:

Timestamp startTs = Timestamp.valueOf(startOfDay);
Timestamp endTs = Timestamp.valueOf(endOfDay);
于 2021-09-15T11:30:40.097 回答
-2
public static Date beginOfDay(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);

    return cal.getTime();
}

public static Date endOfDay(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 23);
    cal.set(Calendar.MINUTE, 59);
    cal.set(Calendar.SECOND, 59);
    cal.set(Calendar.MILLISECOND, 999);

    return cal.getTime();
}
于 2016-11-26T06:07:12.740 回答