java 一天的结束时间_java - 如何获取一天的开始时间和结束时间?-程序员宅基地

技术标签: java 一天的结束时间  

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

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

这样的代码不准确:

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();

}

它毫不准确到毫秒。

kalman03 asked 2019-08-28T21:05:53Z

11个解决方案

127 votes

Java 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());

}

Update: I've added these 2 methods to my Java Utility Classes here

DateUtils.atStartOfDay

DateUtils.atEndOfDay

它位于Maven Central Repository中:

com.github.rkumsher

utils

1.3

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();

}

RKumsher answered 2019-08-28T21:14:20Z

77 votes

半开

The answer by mprivat is correct. His point is to not try to obtain end of a day, but rather compare to "before start of next day". His idea is known as the "Half-Open" approach where a span of time has a beginning that is inclusive while the ending is exclusive.

当前的日期时间框架是Java(java.util.Date/Calendar和Joda-Time),它们都使用了纪元的毫秒数。 但在Java 8中,新的JSR 310 java.time。*类使用纳秒分辨率。 如果切换到新类,基于强制一天中最后一刻的毫秒计数而编写的任何代码都将是不正确的。

如果采用其他分辨率,则比较来自其他来源的数据会出错。 例如,Unix库通常使用整秒,而Postgres等数据库将日期时间解析为微秒。

一些夏令时变化发生在午夜,这可能会进一步混淆事情。

kE3r8.png

Joda-Time 2.3提供了一种方法,用于获取当天的第一时刻:LocalDate。类似于java.time,LocalDate。

Search StackOverflow for "joda half-open" to see more discussion and examples.

比尔施奈德看到这篇文章,时间间隔和其他范围应该是半开放的。

避免遗留日期时间类

众所周知,java.util.Date和.Calendar类很麻烦。 避免他们。

使用Joda-Time或最好使用java.time。 java.time框架是非常成功的Joda-Time库的官方继承者。

java.time

The java.time framework is built into Java 8 and later. Back-ported to Java 6 & 7 in the ThreeTen-Backport project, further adapted to Android in the ThreeTenABP project.

LocalDate是UTC时间轴上的一个时刻,分辨率为纳秒。

Instant instant = Instant.now();

应用时区来获取某个地方的挂钟时间。

ZoneId zoneId = ZoneId.of( "America/Montreal" );

ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

要获得当天的第一个时刻,请通过LocalDate类及其withTimeAtStartOfDay方法。

ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );

使用半开放式方法,获得第二天的第一时刻。

ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );

目前,java.time框架缺少withTimeAtStartOfDay类,如下面针对Joda-Time所述。 但是,ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 其中的类别是withTimeAtStartOfDay.通过传递一对Duration对象构造00:00:00。 我们可以从我们的ZonedDateTime个目标中提取Interval。

Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.toInstant() );

乔达时间

更新:Joda-Time项目现在处于维护模式,并建议迁移到java.time类。 我将这段保留完整的历史记录。

Joda-Time has three classes to represent a span of time in various ways: withTimeAtStartOfDay, 00:00:00, and Duration. An Interval has a specific beginning and ending on the timeline of the Universe. This fits our need to represent "a day".

我们将方法称为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 );

如果必须,您可以转换为java.util.Date。

java.util.Date date = todayStart.toDate();

Basil Bourque answered 2019-08-28T21:12:16Z

24 votes

在getEndOfDay中,您可以添加:

calendar.set(Calendar.MILLISECOND, 999);

Although mathematically speaking, you can't specify the end of a day other than by saying it's "before the beginning of the next day".

So instead of saying, if(date >= getStartOfDay(today) && date <= getEndOfDay(today)), you should say: if(date >= getStartOfDay(today) && date < getStartOfDay(tomorrow)). That is a much more solid definition (and you don't have to worry about millisecond precision).

mprivat answered 2019-08-28T21:16:53Z

6 votes

java.time

使用内置于Java 8中的java.time框架。

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

Przemek answered 2019-08-28T21:17:21Z

2 votes

对于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)

Fırat KÜÇÜK answered 2019-08-28T21:17:54Z

1 votes

使用java8 java.time.ZonedDateTime而不是通过LocalDateTime查找开始日期的其他方法只是将输入ZonedDateTime截断为DAYS:

zonedDateTimeInstance.truncatedTo( ChronoUnit.DAYS );

laur answered 2019-08-28T21:18:22Z

1 votes

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

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的时间

Alexander Chingarev answered 2019-08-28T21:18:55Z

1 votes

Java 8或ThreeTenABP

ZonedDateTime

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

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

我希望能有所帮助。

SudoPlz answered 2019-08-28T21:19:38Z

0 votes

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

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);

Siddhey Sankhe answered 2019-08-28T21:20:05Z

-2 votes

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();

}

jack jin answered 2019-08-28T21:20:24Z

-3 votes

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

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();

}

abdelhadi answered 2019-08-28T21:20:51Z

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_35902426/article/details/114073546

智能推荐

Linux视频学习笔记(九)--yum在线管理、源码包管理与脚本安装包_兄弟连安装gcc-程序员宅基地

文章浏览阅读4k次。声明:本系列文章是博主根据 “兄弟连新版Linux视频教程”做的笔记和视频截图,只为学习和教学使用,不适用任何商业用途。PS:文章基于Linux版本CentOS6.9,如果对Linux感兴趣,建议去看《细说Linux》,沈超老师和李明老师的教学风格我很喜欢:) 6.3 软件包管理-rpm包管理- yum在线管理视频6.3.1 软件包管理-rpm包管理-yum在线管理-IP地址配置和..._兄弟连安装gcc

HTML:本地存储的方法详解:_html本地存储-程序员宅基地

文章浏览阅读2.6k次。HTML:本地存储有四种方式。分别为:cookies、Storage 、Web SQL、IndexedDB。其中前端开发最常用的是Storage。下面来讲解一下他们的具体内容和区别;Cookie:构成: 名称 一个唯一确定cookie的名称 值 储存在cookie中的字符串值 域 cookie对于那个域是有效的 路径 指定域中的指定路径 失效时间 cookie何时应该被删除的时间戳 安全标志 指定后,cookie_html本地存储

CSDN日报19228——这4点微不足道的改变,正在带我起飞_csdn博客-程序员宅基地

文章浏览阅读2.8k次。程序人生 | 这4点微不足道的改变,正在带我起飞作者:沉默王二3个月前,我完全不懂什么叫个人品牌。我在CSDN上纯粹是为了写而写,完全不知道文章的作者——“沉默王二”就是我的个人品牌,就是我以后可以靠它生存的金字招牌。我在2015年就成为CSDN的博客专家了,排名达到1107,但竟然籍籍无名,除了七八个出版社的编辑找我写书外,再没有别的资源链接到我——“变现”和我之间隔着一条难以逾越的“..._csdn博客

白色简洁的瑞班克个人博客网站-程序员宅基地

文章浏览阅读101次。链接:http://pan.baidu.com/s/1eSqSY8E密码:yqaf转载于:https://www.cnblogs.com/wordblog/p/6804750.html_白色博客网站

java-poi实现:合并汇总不同ecxel的同名sheet页数据_java 对excel 数据汇总-程序员宅基地

文章浏览阅读705次。java-poi、excel操作_java 对excel 数据汇总

C++ LeetCode 171 EXCEL表列序号_计算excel的列序号c++-程序员宅基地

文章浏览阅读152次。给定一个Excel表格中的列名称,返回其相应的列序号。例如,A -> 1B -> 2C -> 3...Z -> 26AA -> 27AB -> 28 ...示例 1:输入: “A”输出: 1示例 2:输入: “AB”输出: 28示例 3:输入: “ZY”输出: 701其实就是26进制转10进制class Solution {public: int titleToNumber(string s) { int_计算excel的列序号c++

随便推点

Android WebView 网页使用本地字体_android 字体包给webview使用-程序员宅基地

文章浏览阅读6.5k次,点赞4次,收藏5次。要求在网页里面调用android app中assets目录下的某个字体文件。网页加载通常有两种方式:1、loadDataWithBaseURL2、loadUrl一、loadDataWithBaseURL网页中直接使用file://指定assets文件路径即可示例:font-family: url('file:///android_asset/xxx.TTF')二、loadUr..._android 字体包给webview使用

计算机网络课后作业(3)——数据链路层_6、若数据链路层的发送窗口尺寸wt=4,则在 发送3号帧,并接到2号帧的确认帧后,-程序员宅基地

文章浏览阅读6.1k次,点赞9次,收藏41次。一.单选题(共15题,100.0分)1、若数据链路层的发送窗口尺寸W=4,在发送3号帧、并收到2号帧的确认帧后,发送方还可以连续发送多少个帧?(采用累计确认)A、4B、2C、3D、1答案解析:由于是累计确认,收到2号帧的确认帧,说明2号帧以及之前的帧都被成功接收。可以从第三号帧开始再发4个帧。既然已经发出了一个3号帧并且没收到其确认帧,那就还可以连续发送4-1=3个帧。2、下列关于停-等ARQ协议,正确的描述是?A、仅当当前帧的 ACK 落入 *sent *(发送窗口),发送方发送下一帧B_6、若数据链路层的发送窗口尺寸wt=4,则在 发送3号帧,并接到2号帧的确认帧后,

PHP Laravel基础讲解_php controller 与 blade.php-程序员宅基地

文章浏览阅读786次。laravel目录结构app:laravel项目的核心代码app\Http\Controller.php: 定义控制器bootstrap:app.php:用于框架的启动和自动载入配置cache: 处理缓存config:配置文件database: 数据库public: 定义了项目的入口文件:index.php,localhost:8000,就会访问入口文件,前端静态资源resources: 本地化语言文件routes:路由storage: 要与app文件夹产生联系_php controller 与 blade.php

Java 中的常见错误和可能的错误(转)_exception in thread "thread-3" java.lang.runtimeex-程序员宅基地

文章浏览阅读1.9k次。 0、 需要标识符 a) 不在函数内 1、 非法表达式开始 b) 可能:丢失括号 . 2. no data found a) 可能:setInt(1,100)中,没有100这个值 3. 找不到符号 a) 可能:没导入包 4. 指定了无效URL a) 可能:数据库名或IP错误,即连接出错 5. 类路径没有找到 a) 可能: ClassNotFoundException: oracle.jdbc.dr_exception in thread "thread-3" java.lang.runtimeexception: java.lang.nullpoi

Mysql基础部分(12)---数据的增删改-程序员宅基地

文章浏览阅读198次。以往内容:Mysql基础部分(1)—基础操作指令与语法规范Mysql基础部分(2)—基础查询Mysql基础部分(3)—条件查询Mysql基础部分(4)—排序查询Mysql基础部分(5)—常见函数Mysql基础部分(6)—分组函数Mysql基础部分(7)—分组查询Mysql基础部分(8)—sql99语法Mysql基础部分(9)—子查询Mysql基础部分(10)—分页查询Mysq...

使用matlab绘制世界地图并根据经纬度绘制点位(附m_map的下载与安装说明)_matlab根据经纬度画地图-程序员宅基地

文章浏览阅读6.8w次,点赞74次,收藏410次。使用matlab绘制世界地图有两种方法(自己使用过的,可能有别的我不了解的方法):第一种是worldmap和geoshow;第二种是利用m_map工具箱;下面分别介绍这两种方法。1.worldmap & geoshowworldmap和geoshow是matlab中绘图工具箱的两个绘图函数,直接调用即可。worldmap的语法:worldmap region %r..._matlab根据经纬度画地图