How to obtain the start time and end time of a day?
如何获取一天的开始时间和结束时间?
这样的代码不准确:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); } |
它不精确到毫秒。
Java的8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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()); } |
更新:我已经添加到我的utility 2这些方法的Java类。 P / < >
- dateutils.atstartofday
- dateutils.atendofday
它也在Maven中央repository美元: P / < >
1 2 3 4 5 | <dependency> <groupId>com.github.rkumsher</groupId> utils</artifactId> <version>1.3</version> </dependency> |
Java和earlier 7 与Apache下议院
1 2 3 4 5 6 7 |
没有Apache下议院
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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(); } |
半开放
"mprivat by答案也是的先生。他一点也不去试着获得一天的结束",但比较到"的开始,而在第二天的"。他的主意也被称为"半开放"的方法在学校的时间的开始,而费用支付的结局是专有的。 P / < >
- "当前的日期-时间也frameworks Java(java.util.date /日历和尤达大师的时间)都使用milliseconds从时代。但在Java 8,纽约jsr 310 java.time。*类使用nanoseconds决议。你写的任何代码的基础上forcing的milliseconds count of最后时刻的一天会incorrect如果switched *的新类。
- comparing数据从其他来源变得faulty如果他们运用其他resolutions。例如,UNIX libraries typically运用整个秒,和这样一个databases postgres解决日期-时间到microseconds。
- 一些白天的时间发生在午夜节能的变化,可能会进一步confuse的事情。
P / < >
尤达大师- 2.3时代提供的方法为这一专用,到获得第一矩的一天:
搜索stackoverflow为"尤达大师半开放"看到更多的discussion和examples。 P / < >
看到这个帖子的时候,intervals和其他ranges应该半开放,由比尔施耐德。 P / < > 避免传统的日期时间类
"java.util.date和日历。类是notoriously troublesome。避免他们。 P / < >
无论是使用时间或尤达大师,preferably,java.time。"java.time框架的官方successor *高度成功的尤达大师的时间的图书馆。 P / < > java.time
"java.time框架也建成Java 8和以后。背ported到Java 6 & AMP;7在threeten - backport项目,进一步adapted到Android在threetenabp项目。 P / < >
一个
1 | Instant instant = Instant.now(); |
apply的时间区得到华尔-时钟的时间为一些locality。 P / < >
1 2 | ZoneId zoneId = ZoneId.of("America/Montreal" ); ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); |
得到的第一矩的一天去通过
1 | ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId ); |
用半开放的方法,得到以下的第一刻的一天。 P / < >
1 | ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 ); |
目前的java.time框架缺乏一
1 | Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.toInstant() ); |
尤达大师的时间
更新:尤达大师的时间的项目,现在在我们维修模式,和advises迁移到java.time类。我离开这段intact为历史。 P / < >
尤达大师-时间三类到represent男孩回来了很多的时间在各种方式:
我们知道
例子代码使用Joda时间2.3。 P / < >
1 2 3 4 5 | 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 ); |
如果你要,你可以convert到java.util.date。 P / < >
1 |
在getendofday,你可以给我: P / < >
1 |
虽然mathematically speaklng,你找不specify"结束"的一天超过by说"前开始的第二天。" P / < >
所以代替说,
java.time
用
1 2 3 4 5 6 7 8 9 | 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 |
使用java8 java.time.zonedDateTime而不是通过
1 | zonedDateTimeInstance.truncatedTo( ChronoUnit.DAYS ); |
号
Java 8或三重表分区日期时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
。本地日期时间
1 2 3 4 5 6 7 8 9 10 11 | 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 |
我希望这能帮助别人。
对于Java 8,下面的单行语句正在工作。在这个例子中,我使用的是UTC时区。请考虑更改当前使用的时区。
1 2 3 4 5 6 7 8 9 10 11 | 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); |
如果输出没有时间差。试一试:
我试过这个代码,它运行得很好!
1 2 3 4 5 | 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); |
。
另一个不依赖任何框架的解决方案是:
1 2 3 4 5 6 7 8 9 | 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的时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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(); } |
我试过了这个代码,和它的工作好。: P / < >
1 2 3 4 5 6 7 8 9 10 11 12 | Date d= new Date(); GregorianCalendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); String s_d=d.getYear()+"-"+(d.getMonth()+1)+"-"+d.getDay(); DateFormat dateFormat = DateFormat.getDateInstance(); try { // for the end of day : c.setTime(dateFormat.parse(s_d+" 23:59:59")); // for the start of day: //c.setTime(dateFormat .parse(s_d+" 00:00:00")); } catch (ParseException e) { e.printStackTrace(); } |