Java SimpleDataFormat显示不正确的毫秒,带“0”;S";格式,但不使用“格式”;SSS“;
我遇到一个问题,显示的日期的毫秒分量乘以10 具体而言,当使用Java SimpleDataFormat显示不正确的毫秒,带“0”;S";格式,但不使用“格式”;SSS“;,java,date,simpledateformat,Java,Date,Simpledateformat,我遇到一个问题,显示的日期的毫秒分量乘以10 具体而言,当使用.S格式时,时间52.050显示为52.50,但当使用.SSS格式时,时间52.050 以下面的代码示例为例: //某个50毫秒的任意点 最终日期=新日期(1620946852050 l); final LocalDateTime LocalDateTime=LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault()); 最终字符串格式=“%-40s%-20s%-20
.S
格式时,时间52.050
显示为52.50
,但当使用.SSS
格式时,时间52.050
以下面的代码示例为例:
//某个50毫秒的任意点
最终日期=新日期(1620946852050 l);
final LocalDateTime LocalDateTime=LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault());
最终字符串格式=“%-40s%-20s%-20s%n”;
系统输出格式(格式,“日期格式化程序”、“日期格式”、“格式化输出”);
数据流(“HH:mm:ss”、“HH:mm:ss.S”、“HH:mm:ss.ss”、“HH:mm:ss.ss”).forEach(日期格式->{
System.out.println();
System.out.format(format,simpleDataFormat.class.getName(),dateFormat,
新的SimpleDataFormat(dateFormat).format(date));
System.out.format(format,DateTimeFormatter.class.getName(),dateFormat,
DateTimeFormatter.of模式(dateFormat).format(localDateTime));
});
这将产生以下输出:
Date Formatter Date Format Formatted Output
java.text.SimpleDateFormat HH:mm:ss 00:00:52
java.time.format.DateTimeFormatter HH:mm:ss 00:00:52
java.text.SimpleDateFormat HH:mm:ss.S 00:00:52.50
java.time.format.DateTimeFormatter HH:mm:ss.S 00:00:52.0
java.text.SimpleDateFormat HH:mm:ss.SS 00:00:52.50
java.time.format.DateTimeFormatter HH:mm:ss.SS 00:00:52.05
java.text.SimpleDateFormat HH:mm:ss.SSS 00:00:52.050
java.time.format.DateTimeFormatter HH:mm:ss.SSS 00:00:52.050
我使用了java.util.Date
和java.time
来说明意外行为,我知道java.time
更好,但我仍然想了解SimpleDataFormat
的行为
我运行的是Java 14.0.2.12,但可以在11.0.10.9中重现。传统的日期时间API(Java.util
date-time类型及其格式类型,SimpleDateFormat
)已经过时且容易出错。建议完全停止使用它,并切换到java.time
,即*
让我们了解一下simpleDataFormat
生成的结果是如何令人困惑的(因此容易出错)
1620946852050毫秒=1620946852000毫秒+50毫秒
对于1620946852000,System.out.println(localDateTime)
将生成结果,2021-05-14T00:00:52
50毫秒=(50/1000)秒=0.05秒。这就是DateTimeFormatter
如何显示它的。将S
清楚地描述为:秒的分数。换句话说,它表示为0.05到9位小数(纳秒)的数学浮点数
您可以这样理解:在字符串的右侧填充零。valueOf(0.05)
将精度提高到小数点后9位。因此,它变成了“0.05000000”
。现在,根据S
的数量,获得的子字符串“0.05000000”
。请注意,最多只能在9个位置执行此操作,即ssss
将引发异常
:.0S
:.05SS
:.050SSS
:.0500等,直到SSSS
:.05000000sss
SimpleDateFormat
不会将其表示为秒的分数;相反,它将
之后的数字表示为毫秒数。将S
描述为:毫秒。因此,它表示为50的数学十进制整数。这使它变得混乱,因为我们一看到
,就会想到分数,而SimpleDateFormat
则认为它只是秒和毫秒的分隔符
以下示例说明了这些不同的表示方式:
public class Main {
public static void main(String[] args) {
int sdf = 50;
String dtf = String.format("%.9f", 0.05);
System.out.format("sdf: %01d, dtf: %s%n", sdf, dtf.substring(0, 3));// Including two places for "0."
System.out.format("sdf: %02d, dtf: %s%n", sdf, dtf.substring(0, 4));// Including two places for "0."
System.out.format("sdf: %03d, dtf: %s%n", sdf, dtf.substring(0, 5));// Including two places for "0."
System.out.format("sdf: %04d, dtf: %s%n", sdf, dtf.substring(0, 6));// Including two places for "0."
}
}
输出:
sdf: 50, dtf: 0.0
sdf: 50, dtf: 0.05
sdf: 050, dtf: 0.050
sdf: 0050, dtf: 0.0500
*无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认。从了解有关现代日期时间API的更多信息。
它的工作原理与中所述完全相同,这里没有“不正确”的地方。特别是这样一句话:“图案字母通常是重复的,因为它们的数字决定了确切的表示方式;数字:对于格式化,图案字母的数量是最小位数,较短的数字被零填充到这个数量。”如果你使用java 14,也许考虑使用类而不是类<代码> Simpledateformat < /C>。