如何获得一天的开始时间和结束时间?
这样的代码不准确:
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();
}
Run Code Online (Sandbox Code Playgroud)
它毫不准确到毫秒.
RKu*_*her 156
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());
}
Run Code Online (Sandbox Code Playgroud)
更新:我添加了这2种方法,以我的Java实用工具类在这里
它位于Maven Central Repository中:
<dependency>
<groupId>com.github.rkumsher</groupId>
<artifactId>utils</artifactId>
<version>1.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 91
mprivat的答案是正确的.他的观点是不要试图获得一天的结束,而是要比较"在第二天开始之前".他的想法被称为"半开放式"方法,其中一段时间的开始是包容性的,而结尾是独占的.
Joda-Time 2.3为此目的提供了一种方法,以获得当天的第一时刻:withTimeAtStartOfDay()
.同样在java.time中LocalDate::atStartOfDay
.
搜索StackOverflow"joda half-open"以查看更多讨论和示例.
比尔施耐德看到这篇文章,时间间隔和其他范围应该是半开放的.
众所周知,java.util.Date和.Calendar类很麻烦.避免他们.
使用Joda-Time或最好使用java.time.java.time框架是非常成功的Joda-Time库的官方继承者.
java.time框架内置于Java 8及更高版本中.在ThreeTen- Backport项目中反向移植到Java 6和7,在ThreeTenABP项目中进一步适应Android .
An Instant
是UTC时间轴上的一个时刻,分辨率为纳秒.
Instant instant = Instant.now();
Run Code Online (Sandbox Code Playgroud)
应用时区来获取某个地方的挂钟时间.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Run Code Online (Sandbox Code Playgroud)
要获得当天的第一时刻,请通过LocalDate
课程及其atStartOfDay
方法.
ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );
Run Code Online (Sandbox Code Playgroud)
使用半开放式方法,获得第二天的第一时刻.
ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );
Run Code Online (Sandbox Code Playgroud)
目前,java.time框架缺少Interval
如下Joda-Time所述的类.但是,ThreeTen-Extra项目使用其他类扩展了java.time.该项目是未来可能添加到java.time的试验场.其中的课程是Interval
.Interval
通过传递一对Instant
对象来构造一个.我们可以Instant
从我们的ZonedDateTime
对象中提取.
Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.toInstant() );
Run Code Online (Sandbox Code Playgroud)
更新:Joda-Time项目现在处于维护模式,并建议迁移到java.time类.我将这段保留完整的历史记录.
乔达时间有三个类来表示各种方式的时间跨度:Interval
,Period
,和Duration
.An Interval
具有特定的开始和结束于宇宙的时间线.这符合我们代表"一天"的需要.
我们称之为方法,withTimeAtStartOfDay
而不是将时间设置为零.由于夏令时和其他异常,一天的第一时刻可能不会00:00:00
.
使用Joda-Time 2.3的示例代码.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( timeZone );
DateTime todayStart = now.withTimeAtStartOfDay();
DateTime tomorrowStart = now.plusDays( 1 ).withTimeAtStartOfDay();
Interval today = new Interval( todayStart, tomorrowStart );
Run Code Online (Sandbox Code Playgroud)
如果必须,您可以转换为java.util.Date.
java.util.Date date = todayStart.toDate();
Run Code Online (Sandbox Code Playgroud)
mpr*_*vat 28
在getEndOfDay中,您可以添加:
calendar.set(Calendar.MILLISECOND, 999);
Run Code Online (Sandbox Code Playgroud)
虽然从数学上讲,除了说"在第二天开始之前"之外,你不能指定一天结束.
所以不if(date >= getStartOfDay(today) && date <= getEndOfDay(today))
应该说,你应该说:if(date >= getStartOfDay(today) && date < getStartOfDay(tomorrow))
.这是一个更加可靠的定义(您不必担心毫秒精度).
使用java.time
Java 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
Run Code Online (Sandbox Code Playgroud)
使用 java8 java.time.ZonedDateTime 查找一天的开始而不是遍历的其他方法LocalDateTime
是将输入 ZonedDateTime 截断为 DAYS:
zonedDateTimeInstance.truncatedTo( ChronoUnit.DAYS );
Run Code Online (Sandbox Code Playgroud)
#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 /sf/answers/2040212051/
Run Code Online (Sandbox Code Playgroud)
###本地日期时间
LocalDateTime curDate = LocalDateTime.now();
public LocalDateTime startOfDay() {
return curDate.atStartOfDay();
}
public LocalDateTime endOfDay() {
return curDate.atTime(LocalTime.MAX); //23:59:59.999999999;
}
// based on /sf/answers/2548610851/
Run Code Online (Sandbox Code Playgroud)
我希望这对某人有帮助。
归档时间: |
|
查看次数: |
154636 次 |
最近记录: |