Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SimpleDataFormat显示不正确的毫秒,带“0”;S";格式,但不使用“格式”;SSS“;_Java_Date_Simpledateformat - Fatal编程技术网

Java SimpleDataFormat显示不正确的毫秒,带“0”;S";格式,但不使用“格式”;SSS“;

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

我遇到一个问题,显示的日期的毫秒分量乘以10

具体而言,当使用
.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
将引发异常

  • S
    :.0
  • SS
    :.05
  • SSS
    :.050
  • SSSS
    :.0500等,直到
  • sss
    :.05000000
这是我们小时候在数学中学习分数时所学的表示法

另一方面,
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>。