JavaSpringMySQL字符串时区列介于两毫秒之间

bsxbgnwa  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(214)

我在mysql列中获得了一个存储为字符串的时区日期,格式如下:
2018-07-23t20:54:37.242z-->开始日期
我要做的是两毫秒(或日期)之间的一个比较,如下所示:

SELECT * FROM activity_entity WHERE start_date BETWEEN 1532322000000 AND 1532408399000

另外,我使用java spring repository作为后端,在这里我发送如下参数:

Date since = new Date(accessRepPOSTInDto.getSince()); //1532322000000 gives Mon Jul 23 00:00:00 CDT 2018
Date to = new Date(accessRepPOSTInDto.getTo());//1532408399000 gives Mon Jul 23 23:59:59 CDT 2018

@Query(value = "SELECT * FROM activity_entity WHERE start_date BETWEEN :since AND :too , nativeQuery = true)
ActivityEntity findBetweenDates(@Param("since") Date since, @Param("too") Date too);

做这件事会使你感到沮丧;
我认为mysql可以自动格式化两个日期和字符串列来完成中间的操作,但看起来没有。
任何帮助都会非常感激。当做。

wpx232ag

wpx232ag1#

在本机查询中,需要显式地将varchar列的值强制转换为between操作符要计算的正确日期/时间戳。本机查询应该是这样的:

SELECT * FROM activity_entity WHERE STR_TO_DATE(start_date, '%Y-%c-%eT%H:%i:%s.%fZ') BETWEEN :since AND :too
wmtdaxz3

wmtdaxz32#

热释光;博士

sql语句:

SELECT * FROM tbl WHERE event >= ? AND event < ? ;  -- Using Half-Open approach where beginning is *inclusive* while the ending is *exclusive*.

java 语:

myPreparedStatement.setString( 1 , Instant.ofEpochMilli( 1_532_322_000_000L ).toString() ) ;
myPreparedStatement.setString( 2 , Instant.ofEpochMilli( 1_532_408_399_000L ).toString() ) ;

iso 8601标准

2018-07-23t20:54:37.242z
此格式的文本符合iso 8601标准。该标准是将日期时间值表示为文本的最佳方式。但是在数据库中,应该使用专门构建的数据类型,定义一个类似于sql标准的列类型 TIMESTAMP WITH TIME ZONE . 搜索堆栈溢出以获取更多信息。
在解析/生成字符串时,java.time类默认使用iso8601格式。所以不需要指定格式化模式。

Instant instant = Instant.parse( "2018-07-23T20:54:37.242Z" ) ;

从纪元开始计数

您可以使用 Instant 班级。

Instant start = Instant.ofEpochMilli( 1_532_322_000_000L ) ;
Instant stop = Instant.ofEpochMilli( 1_532_408_399_000L ) ;

以数据库列中使用的标准iso8601格式生成字符串。

String startStr = start.toString() ;
String stopStr = stop.toString() ;

避免遗留日期时间类

与最早版本的java捆绑在一起的旧日期时间类非常糟糕。永远不要使用它们。它们已被java.time类完全取代。

半开

我想做的是
这个 BETWEEN sql中的命令通常不应与日期时间值一起使用。该命令是完全“关闭”的,意味着开始和结束都是包含的。
相反,对于日期时间工作,通常最好将时间跨度定义为半开放时间。在这种方法中,开头是包含的,而结尾是独占的。例如,从中午到下午1点因午休而被解雇的学生预计会在时钟敲响1点和铃声响起之前回到座位上。另一个例子是,一周从周一开始,一直持续到下周一,但不包括下周一。
在sql代码中,这意味着查询使用 >= , AND ,和 < .

SELECT *
FROM tbl
WHERE event >= ?
AND event < ?
;

由于iso 8601格式与 Z 是按时间顺序的,按字母顺序排序时,可以使用ISO8601字符串进行此操作。

myPreparedStatement.setString( 1 , startStr ) ;
myPreparedStatement.setString( 2 , stopStr ) ;

如果你用过 TIMESTAMP WITH TIME ZONE 如上所述,只需传递 Instant 物体。

myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;

如果您真的必须使用完全封闭的方法,请调整查询运算符 >= , AND ,和 <= . 或者打电话 BETWEEN .
我不是一个spring用户,在这方面帮不了你。

关于java.time

java.time框架内置于Java8及更高版本中。这些类取代了旧的遗留日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .
现在处于维护模式的joda time项目建议迁移到java.time类。
要了解更多信息,请参阅oracle教程。和搜索堆栈溢出的许多例子和解释。规格为jsr 310。
您可以直接与数据库交换java.time对象。使用符合jdbc 4.2或更高版本的jdbc驱动程序。不需要线,不需要线 java.sql.* 班级。
从哪里获得java.time类?
java se 8、java se 9、java se 10及更高版本
内置的。
标准javaapi的一部分,带有一个捆绑的实现。
Java9添加了一些次要的特性和修复。
java se 6和java se 7
大部分java.time功能都是通过310个后端口后端口移植到Java6和Java7的。
安卓
android包java.time类的更高版本实现。
对于早期的android(<26),threetenabp项目采用了threeten backport(如上所述)。了解如何使用threetenabp…。
threeten额外的项目用额外的类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter ,等等。

相关问题