调用getAllInvoice返回空列表:如何获取Long格式存储的发票Observable列表
解决DatePicker日期匹配Long类型存储日期的发票查询问题
看起来你遇到的核心问题是DatePicker的LocalDate和数据库里的Long时间戳不匹配,直接转成单个Date去查询只会匹配精确的时间点,而不是全天的发票,所以返回空列表。下面给你一步步的解决方案:
第一步:把LocalDate转换成当天的时间范围(起始/结束时间戳)
数据库里的Long通常是从1970年开始的毫秒级时间戳,代表具体的某一分某一秒。要查询当天所有发票,你需要获取当天00:00:00到次日00:00:00的时间戳区间,这样就能覆盖当天所有时刻的记录:
DatePicker datePicker = new DatePicker(); datePicker.setPrefWidth(width); datePicker.setValue(LocalDate.now()); // 获取选中日期的当天起始和次日起始的LocalDateTime LocalDate selectedDate = datePicker.getValue(); LocalDateTime startOfDay = selectedDate.atStartOfDay(); LocalDateTime endOfDay = selectedDate.plusDays(1).atStartOfDay(); // 转换为Long类型的毫秒时间戳(注意时区要和数据库存储时一致) ZoneId zone = ZoneId.systemDefault(); // 用系统默认时区,或者和数据库匹配的时区 long startTimestamp = startOfDay.atZone(zone).toInstant().toEpochMilli(); long endTimestamp = endOfDay.atZone(zone).toInstant().toEpochMilli();
第二步:调整查询方法,按时间范围获取发票列表
你需要修改getAllInvoice方法,让它支持按时间区间查询,而不是单个日期。如果原来的方法只能接受Date,可以重载一个接受Long区间的版本:
// 重载后的查询方法,返回ObservableList<Invoice> public ObservableList<Invoice> getAllInvoice(long startTimestamp, long endTimestamp) { // 这里替换成你的数据库查询逻辑,比如用JDBC或者ORM框架 // 核心是筛选timestamp在[startTimestamp, endTimestamp)区间内的记录 String sql = "SELECT * FROM invoices WHERE invoice_timestamp >= ? AND invoice_timestamp < ?"; // 执行查询并映射为Invoice对象,最后转成ObservableList List<Invoice> invoiceList = jdbcTemplate.query(sql, new Object[]{startTimestamp, endTimestamp}, (rs, rowNum) -> new Invoice( rs.getLong("id"), rs.getString("number"), rs.getLong("invoice_timestamp"), // 其他字段映射... ) ); return FXCollections.observableArrayList(invoiceList); }
第三步:调用调整后的方法
现在你可以用转换好的时间戳区间调用方法,就能拿到当天所有的发票了:
ObservableList<Invoice> invoices = getAllInvoice(startTimestamp, endTimestamp);
关键注意点
- 时区一致性:确保转换时间戳时用的时区和数据库存储发票日期时的时区一致,否则会出现日期偏移(比如东八区的当天0点在UTC是前一天的16点,会导致查询错误)。
- 区间边界:用
>= start和< end而不是<= end,避免把次日0点的记录也查进来。 - 如果你的
getAllInvoice必须保留原参数(比如只接受Date),可以在方法内部把Date转换成时间范围再查询,逻辑和上面一致。
内容的提问来源于stack exchange,提问作者Asaduzzaman Shishir
相关产品推荐
相关产品推荐

