PNS*_*PNS 21 java milliseconds simpledateformat
根据SimpleDateFormat类文档,Java它的日期模式不支持超过毫秒的时间粒度.
所以,日期字符串就像
通过模式解析时
实际上将.符号后面的整数解释为(接近10亿!)毫秒,而不是纳秒,导致日期
即超过11天.令人惊讶的是,使用较少数量的S符号仍会导致所有9位数被解析(而不是,例如,最左边的3位.SSS).
有两种方法可以正确处理此问题:
是否有任何其他方法可以通过向标准SimpleDateFormat实现提供模式来获得正确的解决方案,而无需任何其他代码修改或字符串操作?
Bas*_*que 27
LocalDateTime.parse( // With resolution of nanoseconds, represent the idea of a date and time somewhere, unspecified. Does *not* represent a moment, is *not* a point on the timeline. To determine an actual moment, place this date+time into context of a time zone (apply a `ZoneId` to get a `ZonedDateTime`).
"2015-05-09 00:10:23.999750900" // A `String` nearly in standard ISO 8601 format.
.replace( " " , "T" ) // Replace SPACE in middle with `T` to comply with ISO 8601 standard format.
) // Returns a `LocalDateTime` object.
Run Code Online (Sandbox Code Playgroud)
不,你不能使用SimpleDateFormat来处理纳秒.
但你的前提是......
Java 在其日期模式中不支持超过毫秒的时间粒度
...从Java 8,9,10及更高版本开始,内置java.time类不再适用.并不是Java 6和Java 7也是如此 ,因为大多数java.time 功能都是后端移植的.
SimpleDateFormat,以及相关的java.util.Date/ .Calendar班现在由新过时java.time在Java中8(发现包教程).
新的java.time类支持纳秒分辨率.该支持包括解析和生成九位数的小数秒.例如,当您使用java.time.format DateTimeFormatterAPI时,S模式字母表示"秒的一小部分"而不是"毫秒",它可以处理纳秒值.
Instant例如,Instant该类表示UTC中的时刻.其toString方法String使用标准ISO 8601格式生成对象.在Z上月底表示UTC,发音为"祖鲁".
instant.toString() // Generate a `String` representing this moment, using standard ISO 8601 format.
Run Code Online (Sandbox Code Playgroud)
2013-08-20T12:34:56.123456789Z
请注意,捕获Java 8中的当前时刻仅限于毫秒级分辨率.该java.time类可以保持在纳秒的值,但只能确定当前时间毫秒.这种限制是由于实施Clock.在Java 9及更高版本中,新的Clock实现可以以更精细的分辨率获取当前时刻,具体取决于主机硬件和操作系统的限制,通常是我的经验中的微秒.
Instant instant = Instant.now() ; // Capture the current moment. May be in milliseconds or microseconds rather than the maximum resolution of nanoseconds.
Run Code Online (Sandbox Code Playgroud)
LocalDateTime您的示例输入字符串2015-05-09 00:10:23.999750900缺少时区指示符或UTC的偏移量.这意味着它并没有代表了一下,是不是在时间轴上的一个点.相反,它代表了全球约26-27小时范围内的潜在时刻.
将此类输入视为LocalDateTime对象.首先,将a中间的SPACE替换T为符合ISO 8601格式,在解析/生成字符串时默认使用.因此无需指定格式化模式.
LocalDateTime ldt =
LocalDateTime.parse(
"2015-05-09 00:10:23.999750900".replace( " " , "T" ) // Replace SPACE in middle with `T` to comply with ISO 8601 standard format.
)
;
Run Code Online (Sandbox Code Playgroud)
java.sql.Timestamp该java.sql.Timestamp班也处理纳秒级的分辨率,但在一个尴尬的方式.通常最好在java.time类中完成你的工作.Timestamp从JDBC 4.2及更高版本开始,无需再次使用.
myPreparedStatement.setObject( … , instant ) ;
Run Code Online (Sandbox Code Playgroud)
并检索.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Run Code Online (Sandbox Code Playgroud)
OffsetDateTimeInstantJDBC规范没有强制要求支持,但是OffsetDateTime.因此,如果上述代码因JDBC驱动程序而失败,请使用以下代码.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Run Code Online (Sandbox Code Playgroud)
并检索.
Instant instant = myResultSet.getObject( … , OffsetDateTime.class ).toInstant() ;
Run Code Online (Sandbox Code Playgroud)
如果使用较旧的4.2之前的JDBC驱动程序,则可以使用toInstant和from方法在java.sql.Timestampjava.time 之间来回切换.这些新的转换方法已添加到旧的遗留类中.
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.
flo*_*rad 16
我发现涵盖日期时间格式的多种变体非常棒,如下所示:
final DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21797 次 |
| 最近记录: |