我在MongoDB
中搜索记录的开始日期为"2016-06-01",结束日期为"201607-01"(字符串格式)。在使用java.util.Date
或MongoDB
支持的任何其他程序的Java中,需要指针/指南将开始时间(00:00:00.000)附加到开始日期,并将最长时间(23.59.59.999)附加到结束日期,如下所示。
Example :
Start Date+with time : 2016-06-01T00:00:00.000
End Date+with time : 2016-07-01T23:59:59.999
您可以使用DateTimeFormatter.ISO_LOCAL_DATE_TIME
。以下是一个例子,可能会让你了解你正在尝试做什么:
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String startTime = "T00:00:00.000";
String endTime = "T23:59:59.999";
//here I used the LocalDateTime parser to parse the data+startTime/endTime
LocalDateTime startLocalDateTime = LocalDateTime.parse("2016-07-01"+startTime);
LocalDateTime endLocalDateTime = LocalDateTime.parse("2016-07-01"+endTime );
//with the LocalDateTime, you can then to whatever you want
//as an example, I am parsing it using ISO_LOCAL_DATE_TIME :
String strinStartTime= dtf.format(LocalDateTime.parse("2016-07-22"+startTime));
我希望这能有所帮助;
tl;dr
ZoneId zoneId = ZoneId.of( "Europe/Paris" ) ;
LocalDate startDate = LocalDate.of( "2016-06-01" ) ;
ZonedDateTime zdt start = startDate.atStartOfDay( zoneId ) ;
ZonedDateTime zdt stop = startDate.plusMonths(1).atStartOfDay( zoneId ) ;
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
如果你需要字符串…
String outputStart = start.toInstant().toString() ; // 2016-05-31T22:00:00Z Paris in the summer is two hours ahead of UTC.
String outputStop = stop.toInstant().toString() ; // 2016-06-30T22:00:00Z
详细信息
ishmaelMakitla的Answer很好,因为它指向使用java 8及更高版本中内置的java.time类。但它关注的是字符串而不是对象。此外,它也没有讨论时区的关键问题。
java.time类包括:
LocalDate
表示不带时间和时区的仅限日期的值LocalTime
表示一天中没有日期和时区的时间值。LocalDate startDate=LocalDate.parse("2016-06-01");//正在分析ISO 8601标准日期格式。LocalTime startTime=LocalTime。MIN;//'00:00’。
这两个类都可以在工厂方法中用于实例化LocalDateTime
和其他类。
LocalDateTime ldt = LocalDateTime.of( startDate , startTime );
在上面的代码中,我们使用LocalTime.MIN
来获得00:00
。要直接回答您的问题,您也可以以相同的方式使用LocalTime.MAX
来获得23:59:59.999999999
。但我不建议这么做。阅读下面关于"半开放"的内容。
时区
时区对于确定日期和时间至关重要。在任何特定时刻,日期和时间都会因时区而异。午夜过后几分钟的巴黎是新的一天,而在蒙特利尔仍然是"昨天"。
Local…
类型是而不是时间线上的实际时刻。它们代表了关于可能的时刻的模糊概念。如上所述,6月1日在巴黎的第一个时刻同时是5月31日下午6点在蒙特利尔。因此,在执行数据库搜索之前,您需要为LocalDateTime
分配一个时区。应用ZoneId
将生成ZonedDateTime
对象。
也许你的约会时间是巴黎。
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ldt.atZone( zoneId );
或者你打算使用UTC。这一切都取决于你的商业规则,你的应用程序运行的环境。对于UTC,我们使用OffsetDateTime
,因为UTC不是一个完整的时区,而只是与UTC的偏移。时区是一个偏移量加上一组用于处理异常情况的规则,如夏令时(DST)。
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
要获得问题中要求的字符串,请提取LocalDate并调用toString()
。但我不建议这样做,因为它忽略了时区(请往下看)。
String output = odt.toLocalDateTime.toString(); // Not likely to be what you really need.
数据库中的最佳做法是以UTC存储日期时间。我不知道MongoDB。请务必阅读有关Java中的数据库驱动程序如何影响/转换您指定的值的文档。
一天的开始
请注意,一天并非总是从00:00:00
开始。在某些时区,夏令时或其他异常意味着一天可能在其他时间开始,如01:00
。
在某些情况下,java.time类将根据需要进行调整。一定要阅读课堂文档,这样你就可以看到行为是否符合你的期望&需求。
您可以询问java.time来查找开始时间。
ZonedDateTime zdt = LocalDate.of( "2016-06-01" ).atStartOfDay( zoneId );
半开
你试图确定一天结束的时间是个问题。最后一秒是无限可分的。传统的面向Unix的库解析为整秒,Java中的旧日期时间类解析为毫秒,一些数据库(如Postgres)可能解析为微秒,Java.time和其他数据库(如H2)解析为纳秒。不要介入其中。
通常在一段时间的日期时间编程中,最佳实践是"半开放"。跨度的开头是包含的,而结尾是不包含的。
因此,在巴黎地区搜索一个月的数据意味着搜索日期时间等于或晚于开始日期且小于(但不包括)停止日期 同样,UTC而不是巴黎的记录月份。 在整个应用程序中持续使用半开放方法,处理时间跨度将使您的代码更明智、更容易理解。你也可以训练你的用户以这种方式思考。在"午休时间为12:00至13:00"这样的情况下,我们都会直观地使用Half-Open。我们都知道这意味着在时钟敲响ZoneId zoneId = ZoneId.of( "Europe/Paris" );
LocalDate startDate = LocalDate.of( "2016-06-01" );
ZonedDateTime zdt start = startDate.atStartOfDay( zoneId );
ZonedDateTime zdt stop = startDate.plusMonths(1).atStartOfDay( zoneId );
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
ZoneOffset zoneOffset = ZoneOffset.UTC;
LocalDate startDate = LocalDate.of( "2016-06-01" );
OffsetDateTime start = OffsetDateTime.of( startDate , zoneOffset );
OffsetDateTime stop = OffsetDateTime.plusMonths(1).of( startDate , zoneOffset );
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
13:00:00.0
之前吃完午饭就回来了。
公共类DateSample{
public static void main(String[] args) throws ParseException {
String startDate = "2016-06-01";
String endDate = "2016-07-01";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date strDate = formatter.parse(startDate+" 00:00:00.000");
Date enDate = formatter.parse(endDate+" 23:59:59.999");
System.out.println(formatter.format(strDate));
System.out.println(formatter.format(enDate));
}
}
你会得到2016年6月1日00:00:002016-07-01 23:59:59
如果您在jdk 1.8下运行,请使用LocalDateTime
LocalDateTime是jdk1.8的一个嵌入式api。您可以在这里找到解释docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html。您可以使用减号*或加号*,并解析方法