如何从时间戳对象获取日期?

时间:2019-07-03 18:35:09

标签: java

我将这种格式的日期存储在数据库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()获取数据库中存储的日期和时间

如何实现我想要的?

3 个答案:

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