我将这种格式的日期存储在数据库2019-07-03 12:14:11中,所以当我从数据库中获取日期时,它带有时间戳,但我只想要日期,以便可以将其用作我的TreeMap的键,以便根据Date排序TreeMap。
例如。
假设我在数据库中有与这些日期相关的数据
2019-07-03 12:14:11 and
2019-07-03 12:14:27
现在两个日期都相同,但是时间不同,所以当我将其存储在TreeMap对象中时
TreeMap<Date,List<Integer>> t=new TreeMap<>();
然后,尽管日期与时间相同,但TreeMap将日期存储在我想要的不同键中,因为两个日期都相同,所以与两个日期关联的数据应仅存储在一个键中。
如果与第一个变量关联的数据为1而第二个日期为2,则应在TreeMap中将其存储在List中的1和2的一个键下,并且如果另一个数据3与2019-07-01 12:12:12关联那么它应该存储在另一个密钥中,并且密钥应该排序
我写了这个
if(map.containsKey(invoiceHeader.getInvoice_Date()))
{
List<Integer> invoicesList= map.get(invoiceHeader.getInvoice_Date());
invoicesList.add(invoiceId);
map.put(invoiceHeader.getInvoice_Date(),invoicesList);
}
else {
List<Integer> invoicesList=new ArrayList<>();
invoicesList.add(invoiceId);
map.put(invoiceHeader.getInvoice_Date(),invoicesList);
}
但是这里的键存储日期和时间,即使
2019-07-03 12:14:11 and
2019-07-03 12:14:27
创建了相同的2个键,其中1个存储在一个键中,另2个存储在另一个键中,因为getInvoice_Date()获取数据库中存储的日期和时间
如何实现我想要的?
答案 0 :(得分:3)
请勿使用古老的bind
对象。使用新的Java 8 Time API,即将java.util.Date
日期字符串解析为LocalDateTime
对象,然后调用toLocalDate()
以获取仅日期的LocalDate
值,然后该值成为地图中的键(2019-07-03 12:14:11
)。
您的代码应为:
Map<LocalDate, List<Integer>>
如果map.computeIfAbsent(invoiceHeader.getInvoice_Date().toLocalDate(), x -> new ArrayList<>())
.add(invoiceId);
返回一个getInvoice_Date()
,则可以这样获得java.util.Date
值:
LocalDate
结合上面的代码可以给您:
Instant invoiceInstant = invoiceHeader.getInvoice_Date().toInstant();
LocalDateTime invoiceDateTime = LocalDateTime.ofInstant(invoiceInstant, ZoneId.systemDefault());
LocalDate invoiceDate = invoiceDateTime.toLocalDate();
答案 1 :(得分:2)
在这里您添加/获取日期和时间作为地图中的键。它将无法正常工作,因为如果您希望能够为同一日期使用相同的键但使用不同的时间,则必须添加没有时间的日期。
请注意,您应该使用LocalDateTime
而不是Date
,因为这是一种设计更好的API,并且具有不可变的优势,建议使用映射键。
只需进行一些更改即可:
LocalDate date = invoiceHeader.getInvoice_Date().toLocalDate();
if(map.containsKey(date)){
map.get(date).add(invoiceId);
}
else{
List<Integer> invoicesList = new ArrayList<>();
invoicesList.add(invoiceId);
map.put(date,invoicesList);
}
使用Map.computeIfAbsent()
提供流畅的API:您可以简化整个逻辑,例如:
LocalDate date = invoiceHeader.getInvoice_Date().toLocalDate();
map.computeIfAbsent(date, k-> new ArrayList<>()).add(invoiceId);
答案 2 :(得分:1)
假定您将时刻存储在数据库中与标准SQL TIMESTAMP WITH TIME STAMP
类似类型的列中,然后以java.time.OffsetDateTime
的形式从数据库中检索值。 java.util.Date
类存在严重缺陷,几年前通过采用JSR 310而成为旧类。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
您说您只关心日期。但是要获取日期需要一个时区。检索到的OffsetDateTime
可能采用UTC,尽管这取决于您的特定数据库系统。 SQL标准对日期时间类型的定义不多。我遇到的大多数数据库(例如Postgres和H2)都会在保存到数据库的过程中调整对UTC的任何输入。
请记住,在任何给定时刻,日期都会随时区在全球范围内变化。在日本东京可能是“明天”,而在魁北克蒙特利尔仍然是“昨天”。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
提取仅日期部分。
LocalDate ld = zdt.toLocalDate() ;
您应该已经建立了Map
。
Map < LocalDate, List < Integer > > map = new TreeMap <> ( );
让我们对您的发票标识符的示例进行硬编码。
Integer id = 707;
您可以使用putIfAbsent
来缩短在Question中看到的代码。
map.putIfAbsent ( ld , new ArrayList <> () );
获取List
的发票编号中的Integer
。
List< Integer > list = map.get( ld ) ;
添加我们的发票ID。
list.add( id ) ;
我们可以将最后两个步骤合并为一行。
map.get( ld ).add( id );