tl;博士
Instant // Represent a moment as a count since the epoch reference of 1970-01-01T00:00Z.
.ofEpochSecond( // Instantiate a `Instant` as a count of whole seconds plus fractional second.
TimeUnit.MICROSECONDS.toSeconds( microseconds ) , // Count of whole seconds since the epoch reference.
TimeUnit.MICROSECONDS.toNanos( microseconds ) // Calculate fractional second as a count of nanoseconds.
-
TimeUnit.SECONDS.toNanos(
TimeUnit.MICROSECONDS.toSeconds( microseconds )
)
) // Returns an `Instant`.
.toString() // Generate text in standard ISO 8601 format.
.replace( "T" , " " ) // Replace a `T` with a SPACE for desired output format.
.replace( "Z" , "" ) // Remove the `Z` from the end, that indicates the date and time is in the context of UTC.
避免使用旧的日期时间类
您正在使用糟糕的日期时间类,这些类在几年前被 JSR 310 中定义的现代 java.time 类所取代。
此外,正如其他人指出的那样,旧类无法容纳微秒,只能容纳毫秒。好吧,实际上,遗留类java.sql.Timestamp 试图表示纳秒,但这样做是通过一种可怕的黑客行为来实现的,其中包括以毫秒为单位的小数秒和纳秒的小数秒(真是一团糟)。
java.time
样本数据
作为演示,让我们创建自 1970 年第一刻 UTC 以来的微秒样本数。
// Convert to microseconds. Use as input value to further code below.
Instant instantPrime = Instant.now().truncatedTo( ChronoUnit.MICROS ); // Drop any nanoseconds, to keep only microseconds.
long wholeSecondsPrime = instantPrime.getEpochSecond();
long nanoAdjustmentPrime = instantPrime.getNano();
long microseconds =
TimeUnit.SECONDS.toMicros( wholeSecondsPrime ) +
TimeUnit.NANOSECONDS.toMicros( nanoAdjustmentPrime )
;
处理
让我们将微秒计数分成两部分,自 1970-01-01T00:00Z 以来的整秒数,以及微秒数的小数秒。
// Convert from microseconds.
long wholeSeconds = TimeUnit.MICROSECONDS.toSeconds( microseconds );
long nanoAdjustment = TimeUnit.MICROSECONDS.toNanos( microseconds ) - TimeUnit.SECONDS.toNanos( wholeSeconds );
将它们重新组合在一起。
Instant instant = Instant.ofEpochSecond( wholeSeconds , nanoAdjustment );
boolean match = instant.equals( instantPrime );
转储到控制台。
System.out.println( "instantPrime = " + instantPrime );
System.out.println( "wholeSecondsPrime = " + wholeSecondsPrime );
System.out.println( "nanoAdjustmentPrime = " + nanoAdjustmentPrime );
System.out.println( "microseconds = " + microseconds );
System.out.println( "wholeSeconds = " + wholeSeconds );
System.out.println( "nanoAdjustment = " + nanoAdjustment );
System.out.println( "instant = " + instant );
System.out.println( "match = " + match );
instantPrime = 2020-01-07T23:32:26.385565Z
wholeSecondsPrime = 1578439946
nanoAdjustmentPrime = 385565000
微秒 = 1578439946385565
wholeSeconds = 1578439946
纳米调整 = 385565000
即时 = 2020-01-07T23:32:26.385565Z
匹配 = 真
字符串
使用标准 ISO 8601 格式生成代表 Instant 值的文本。
String output = instant.toString() ;
2020-01-07T23:32:26.385565Z
您想要的格式已接近该格式。将T 替换为空格。并删除Z,但要小心。将日期时间显示为文本而不指示时区或与 UTC 的偏移可能会给读者带来歧义和困惑。我建议包括Z。
String output = instant.toString().replace( "T" , " " ).replace( "Z" , "" ) ;
2020-01-07 23:32:26.385565
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。