Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查询两个日期之间的数据_Java_Datetime_Datetime Comparison - Fatal编程技术网

Java 查询两个日期之间的数据

Java 查询两个日期之间的数据,java,datetime,datetime-comparison,Java,Datetime,Datetime Comparison,我需要从在线服务器中托管的Mongodb数据中获取两个日期之间的数据。我尝试了这段代码,它在我的本地主机(本地数据和实时数据)中运行良好。但是当我在网上上传应用程序时,它在Live中无法正常工作 现场测试结果不准确。它在指定日期之前和之后获取一些记录。例如,我给出了2018年2月1日和2018年2月28日的日期,结果是2018年1月31日和2018年3月1日的记录 我认为问题在于日期存储在UTC时区(2018-02-15T23:33:30.000Z) 代码: java.util.Date,因此解

我需要从在线服务器中托管的Mongodb数据中获取两个日期之间的数据。我尝试了这段代码,它在我的本地主机(本地数据和实时数据)中运行良好。但是当我在网上上传应用程序时,它在Live中无法正常工作

现场测试结果不准确。它在指定日期之前和之后获取一些记录。例如,我给出了2018年2月1日和2018年2月28日的日期,结果是2018年1月31日和2018年3月1日的记录

我认为问题在于日期存储在UTC时区(2018-02-15T23:33:30.000Z)

代码:
java.util.Date
,因此解析和格式化订单日期没有意义。格式化将其转换为
字符串
,解析将其转换回
日期
,这是毫无意义的,因为订单日期已经是
日期
对象

您必须首先在格式化程序中设置时区(变量
format
),然后解析from和to日期:它们将被设置为加尔各答时区的相应日期和时间-在这种情况下,它是有效的,因为您有字符串并希望将其转换为日期

然后使用额外的括号进行比较,以避免任何歧义(如注释中所指出的)。 将
日期
设置为
日历
是没有意义的,只是为了稍后再取回它,
日历
实例在代码中没有任何用途

getOrderDate
的调用不应该在
for
循环中

完整代码如下所示:

SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");      
// from and to dates are from Kolkata's timezone, so the formatter must know that
format.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));      

// dates will be equivalent to this date and time in Kolkata, although
// the date itself doesn't store the timezone in it
Date fromDate = format.parse(from + " 00:00:00");
Date  toDate = format.parse(to + " 23:59:59");

for(Order order : orders){
    Date orderDate = order.getOrderDate();
    // note the extra parenthesis, they make all the difference
    if( (orderDate.after(fromDate) || orderDate.equals(fromDate)) &&
        (orderDate.before(toDate) || orderDate.equals(toDate)) ) {
    ....
    }
}
如果Java>=8,最好使用
Java.time
API:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy");
ZoneId zone = ZoneId.of("Asia/Kolkata");
ZonedDateTime fromDate = LocalDate
    // parse "from" string
    .parse(from, fmt)
    // start of day at Kolkata timezone
    .atStartOfDay(zone);
ZonedDateTime toDate = LocalDate
    // parse "to" string
    .parse(to, fmt)
    // get start of next day
    .plusDays(1).atStartOfDay(zone);

// convert the Date to ZonedDateTime
for (Order order : orders) {
    ZonedDateTime orderDate = order.getOrderDate().toInstant().atZone(zone);
    if ((orderDate.isAfter(fromDate) || orderDate.isEqual(fromDate)) && (orderDate.isBefore(toDate))) {
        ...
    }
}
这是一个不同的代码,因为这个API引入了新的类型和概念,但它比以前的API有了很大的改进(
Date
Calendar
杂乱无章、有缺陷且过时)


花点时间研究一下这个API,它是完全值得的:

如果问题的一部分是您的
。没有括号,它由三个部分条件组成,由
|
(or)分隔,第一个是
orderDate.after(fromDate)
,这就是为什么它接受3月份的日期。我想你的意思是在
和&
之前和之后的每一半都用括号括起来。时区可能是该问题的另一个原因。您正在将
order.getOrderDate()
放入
日历中并再次取出,然后将其格式化为字符串并再次解析回
日期。所有这些不都只是浪费吗?您使用的日期和时间类,
date
Calendar
SimpleDateFormat
,早已过时,最后一个类尤其麻烦。更好地合作,更适合解决时区问题。我建议这样做。我尝试将订单日期从UTC转换为IST,因此我有了calendar对象。我认为
orderDate
的声明应该放在这两个代码段的
for
循环中?Java8版本很棒!我可能会让
fromDate
toDate
成为
Instant
s,以避免为每个订单调用
atZone
,但这只是一个小细节。绝对建议使用半开间隔(从包含到排除)。谢谢你的回答,向上投票。即使使用Java6或Java7,我仍然推荐后者。您只需要获取并将其添加到Java项目中。然后从
Date
Instant
的转换会有一点不同,仅此而已。@OleV.V。我相信
ZonedDateTime
可以让代码更清楚地了解我们用来比较的日期-使用
Instant
需要将思维转换为相应的本地时间,更难调试和维护,我想,你说得对,我更新了,谢谢!你说得有道理。我可能一直在考虑优化,但可能没有理由这样做。@xunts-非常感谢它与Java 8时间代码一起工作
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy");
ZoneId zone = ZoneId.of("Asia/Kolkata");
ZonedDateTime fromDate = LocalDate
    // parse "from" string
    .parse(from, fmt)
    // start of day at Kolkata timezone
    .atStartOfDay(zone);
ZonedDateTime toDate = LocalDate
    // parse "to" string
    .parse(to, fmt)
    // get start of next day
    .plusDays(1).atStartOfDay(zone);

// convert the Date to ZonedDateTime
for (Order order : orders) {
    ZonedDateTime orderDate = order.getOrderDate().toInstant().atZone(zone);
    if ((orderDate.isAfter(fromDate) || orderDate.isEqual(fromDate)) && (orderDate.isBefore(toDate))) {
        ...
    }
}