当前位置: 首页 > 知识库问答 >
问题:

JavaSimpleDateFormat.format()使用毫秒时返回不正确的日期

阴培
2023-03-14

我想将日期字符串从“2016-09-23T09:14:52.555000000”格式解析为“23-SEP-2016”格式。

这是我的密码:

public class Tester {

    public static void main(String[] args) {
        System.out.println(displayDate("2016-09-23T09:14:52.555000000"));
        System.out.println(displayDate("2016-09-28T11:56:24.552000000"));
        System.out.println(displayDate("2016-09-23T09:29:12.507000000"));
        System.out.println(displayDate("2016-09-26T14:55:02.702000000"));
        System.out.println(displayDate("2016-09-26T09:50:24.880000000"));
        System.out.println(displayDate("2016-09-26T15:20:49.397000000"));
        System.out.println(displayDate("2016-09-26T15:21:21.559000000"));
    }

    public static String displayDate(String dateString) {
        String formattedDateString = "NA";

        if(dateString == null) {
            return formattedDateString;
        }

        SimpleDateFormat oracleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.S");
        SimpleDateFormat dateFormatToDisplay = new SimpleDateFormat("dd-MMM-yyyy");

        try {
            Date date = oracleDateFormat.parse(dateString);
            formattedDateString = dateFormatToDisplay.format(date).toUpperCase();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return formattedDateString;
    }

}

问题是如果我用这句台词

SimpleDateFormat oracleDateFormat=新的SimpleDateFormat(“yyyy-MM-dd'T'kk:MM:ss.S”);

输出为(不正确的日期值):

29-SEP-2016
04-OCT-2016
29-SEP-2016
04-OCT-2016
06-OCT-2016
01-OCT-2016
03-OCT-2016

而如果用这条线

oracleDateFormat=new SimpleDateFormat("yyyy-MM-dd'T'kk: mm: ss");

输出为(正确的日期值)

23-SEP-2016
28-SEP-2016
23-SEP-2016
26-SEP-2016
26-SEP-2016
26-SEP-2016
26-SEP-2016

我想知道为什么在格式字符串中添加“S(毫秒)”会导致不正确的值。

即使是“yyyy-MM-dd'T'kk:MM:ss.SSS”也会返回不正确的值。

我正在Android应用程序中使用此代码。它可以在emulator(API 23)上完美地工作。对于某些设备,它显示不正确的日期。它是否与Java版本相关?

共有3个答案

屠锐
2023-03-14

似乎当您添加“S”时,解析器会添加所有毫秒,例如“555000000”。当您进行计算(555000000 ms~6,4d)时,它与结果相匹配(日期不正确)。

您应该使用"yyyy-MM-dd HH: mm: ss.SSS",但也修剪"2016-09-23T09:14:52.555000000"到"2016-09-23T09:14:52.555",例如:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.parse("2016-09-23T09:14:52.555000000".substring(0,23));
樊飞飙
2023-03-14

神秘之处在于S说明符的正确解释。

在SimpleDataFormat的日期和时间模式部分中,S的定义说明:

S毫秒

你觉得它在某些方面很奇怪吗?没有吗?!这也让我大吃一惊,所以让我用消极的方式说:

不是秒的小数部分,而是毫秒

还是不明白吗?我是说字面上的毫秒数。

像在:

  SimpleDateFormat oracleDateFormat = 
    new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.S");
  SimpleDateFormat dateFormatToDisplay = 
    new SimpleDateFormat("dd-MMM-yyyy--HH:mm:ss.SSS");

  Date d=oracleDateFormat.parse("2016-09-23T09:14:52.1");
  System.out.println(dateFormatToDisplay.format(d));

会导致...等待它...嘣...

"2016-09-23--09:14:52.001"

没错,伙计们!一毫秒“不是”和十分之一秒。

那么,如果我们增加点后面的位数,结果会是一样的吗?当然有。

  d=oracleDateFormat.parse("2016-09-23T09:14:52.1000");
  System.out.println(dateFormatToDisplay.format(d));

"2016-09-23--09:14:53.000"

因此,如果你输入T09:14:53.555000000,你只需在基本时间或555000全秒中添加55500000毫秒。这意味着比你的基准时间多出6天10小时11分钟。

边翔宇
2023-03-14

在Java中,这不是几秒钟,而是几毫秒。不要使其大于999。

在Oracle中更改您的日期格式,以包含分数秒的FF3,以产生毫秒。

在Java中,日期格式中的S,或者更确切地说,SSS代表毫秒,即每秒数千。一秒钟只有一千毫秒。

在Oracle中,日期格式不指定毫秒,而是指定几分之一秒。

FF[1..9]
分数秒;不打印基数字符。使用X format元素添加基数字符。使用FF后面的数字1到9指定返回的datetime值的小数部分的位数。如果未指定数字,则Oracle数据库将使用为datetime数据类型指定的精度或该数据类型的默认精度。在时间戳和间隔格式中有效,但在日期格式中无效。

在Java中,如果需要三分之一秒的时间,则无法获得比333毫秒更精确的时间。然而,在Oracle中,您可以将其表示为333微秒,甚至333纳秒。

Oracle允许您指定您想要的十进制位数,但是如果您不这样做,您将获得该类型允许的精度。
那么Java中的日期格式将其解释为毫秒数。数以百万计的人。这些都添加到你约会的其余部分。因为一天只有86,400,000毫秒,超过这一天的任何事情都是你约会的另一天。

让我们来看看你的第一个测试用例,<代码> 2016—09—23 T09:14:52.5500万< /代码>。br>555000000毫秒=555000秒≈ 154小时≈ 6天10小时
在剩下的约会时间(2016-09-23 09:14:52)上再加上6天10小时,你的约会时间应该会增加到2016-09-29 19:00左右。更改输出格式(dateFormatToDisplay)以包含小时数,您将看到发生了什么。

Java日期格式要求毫秒不超过3位数。指定Oracle中的小数位数。FF使用类型的最大精度,FF3仅输出3个小数位数-毫秒。
如果您不能更改Oracle中使用的日期格式,请将其修剪为3个Java中的十进制数字。请注意,任何小于3位数的数字都应该用0填充到3位数的长度;34.12被解释为34秒和12毫秒,而您可能需要120毫秒。

 类似资料:
  • 背景: 在我的数据库表中,我有两个时间戳 当我执行“按时间戳ASC排序”时,时间戳2被认为是更大的时间戳(这是正确的)。 要求:我需要得到这些时间戳的差异(timeStamp2-timeStamp1) 我的实施: 答案应该是238ms,但返回的值是-653ms。我不确定我做错了什么。有什么建议吗?

  • 问题内容: 在pandas数据框中有一个datetime列,其值如下: 我想知道如何舍入这些值,摆脱毫秒,仅将日期,小时,分钟和00表示为秒,如下所示: 问题答案: 使用与用于分钟设置: 我想将时间值更改为下一个值:

  • 问题内容: 我将当前时间(UTC)以纳秒为单位,然后需要以纳秒为单位,然后返回本地时间。我能够将时间缩短到十亿分之一秒,然后再返回到日期字符串,但是当我从字符串转到日期时,时间变得很复杂。 //时间戳正确,但返回的日期不正确 问题答案: 我不明白您为什么要对字符串做任何事情…

  • 我有一个简单的问题: 输出:(我的时区是ICT) 问题是:日历在 DST 日返回此时区的错误时间。时区“美国/圣地亚哥”现在应该是UTC-3(参考:http://www.timeanddate.com/worldclock/chile/santiago)。它需要显示:

  • 所以我当前处于“America/Los_Angeles”时区(PDT)中,但是当我创建一个新的moment对象并通过moment tz将其时区设置为我所在的时区('America/Los_Angeles'),如下所示: 错误的时间被返回。具体来说就是提前8个小时。所有其他时区也会出现这种情况。 我是不是从根本上误解了这是怎么工作的? 谢谢你的帮助!

  • 问题内容: 我想以毫秒为单位,仅包含年,月和日期的当前日期。但是当我使用此代码时: 我仍然以毫秒为单位获取时间。我怎样才能解决这个问题? 问题答案: 请注意日历的时区。