Java中的JDBC时间戳转义格式和SimpleDataFormat

Java中的JDBC时间戳转义格式和SimpleDataFormat,java,timestamp,simpledateformat,Java,Timestamp,Simpledateformat,我正在尝试使用SimpleDateFormat模式来解析和格式化JDBC时间戳,特别是以下格式的日期yyyy-mm-dd hh:mm:ss.fffffffff,其中ffffffffffff表示纳秒 不幸的是新的SimpleDataFormat(“yyyy-MM-dd HH.MM.ss.SSS000000”)不起作用,将引发以下异常: java.text.ParseException: Format.parseObject(String) failed SimpleDataFormat是否可以实

我正在尝试使用
SimpleDateFormat
模式来解析和格式化JDBC时间戳,特别是以下格式的日期
yyyy-mm-dd hh:mm:ss.fffffffff
,其中
ffffffffffff
表示纳秒

不幸的是
新的SimpleDataFormat(“yyyy-MM-dd HH.MM.ss.SSS000000”)
不起作用,将引发以下异常:

java.text.ParseException: Format.parseObject(String) failed
SimpleDataFormat是否可以实现这一点,或者我必须创建java.text.DateFormat的自定义子类来处理这种情况请注意这不是如何在Java中解析
yyyy-mm-dd hh:mm:ss.fffffffff
字符串的问题,我感兴趣的是一种声明性方法,即SimpleDataFormat模式,它不需要对输入字符串进行额外修改

示例

我希望输入
2012-02-05 17:00:34.427000000
解析为java.util.Date,其中毫秒部分为
427

以下是我迄今为止尝试过的格式列表,它们都因各种原因而失败:

  • new SimpleDataFormat(“yyyy-MM-dd-HH.MM.ss.SSS000000”)
    -
    java.text.ParseException:Format.parseObject(String)失败
  • 新的simpledteformat(“yyyy-MM-dd HH:MM:ss.sssss”,Locale.US)
    新的simpledteformat(“yyy-MM-dd HH:MM:ss.SSS”,Locale.US)
    都被解析为Fri-Feb 10 15:37:14,而不是预期的一个太阳Feb 05 17:00:34。(427000000的纳秒部分被视为毫秒,即使只指定了SSS)

编辑:既然您给了我们一个数据示例,它就相当简单了:

"yyyy-MM-dd HH:mm:ss.SSS"
这当然会解析您给定的值。您可能还需要显式指定
Locale.US
,这样它就不会尝试使用不同的分隔符

编辑:超过毫秒的尾随数据会导致问题。但是,数据的早期部分是固定长度的(我相信是23个字符),因此您应该能够编写:

Date date = format.parse(text.substring(0, 23));
的日期模式的格式为:

yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
除非您有来自资源提供商的不同日期格式。”

如果有小数秒:

yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'

编辑:根据您的示例,我用来解析字符串的格式是:

DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");

我知道这是一个迟来的答案,但我一直在研究一个类似的问题,我遇到了这个问题

这里的问题是,
SimpleDataFormat
需要一个
java.util.Date
,它没有纳秒字段。所以,它不处理这种情况。文档中说它是
java.util.Date
和纳秒字段的组合。秒的日期/时间值存储在对象的日期部分。这意味着可以忽略剩余的毫秒,而使用纳秒字段。在我看来,这是一个糟糕的设计,因为
java.sql.Timestamp
java.util.Date
的一个直接子类

无论如何,为了回答这个问题,我认为不可能在不附加由
SimpleDateFormat
生成的字符串的情况下以纳秒打印时间戳

以下是一种方法:

    Timestamp timestamp = new Timestamp(System.currentTimeMillis());
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.");
    format.setTimeZone(TimeZone.getDefault()); // Set the TimeZone to whatever you are expecting.

    System.out.println(format.format(timestamp) + String.format("%09d", timestamp.getNanos());   
编辑:


为纳秒字符串值添加了填充。

“不起作用”非常模糊-会发生什么?引发以下异常:
java.text.ParseException:Format.parseObject(String)失败
我基本上对解析此格式的java.sql.Timestamp日期感兴趣
yyyy-mm-dd hh:mm:ss.fffffffff
,其中
ffffffffff
表示纳秒。@ejboy:那么您希望所有信息都精确到纳秒?你的问题中根本没有提到那一点。请看这不起作用。问题是SSS消耗的是包括零在内的整个部分,而不仅仅是前3位。@ejboy:如果你能给我们一些测试数据,并解释你想要发生什么和发生了什么,那么帮助你就容易多了。你的答案并没有给出正确的结果。检查
newsimpledateformat(“yyyy-MM-dd HH:MM:ss.SSS”,Locale.US)
它返回2月10日15:37:14供我输入。@ejboy:Hmm.正在查看。看起来是额外的0导致了这个问题。@magiconair:当有人问到它时,它就这样做了。OP后来只添加了“不修改输入字符串”的要求。不幸的是,这些模式不包括我的情况。我已经澄清了这个问题。请使用示例作为参考。建议的模式不会导致异常,但日期分析不正确。输入字符串
2012-02-05 17:00:34.427000000
将给出
2012-02-10 15:37:14.000
,作为
.427
之后的尾随零的结果。我想在用
DateFormat
解析日期文本之前,您必须对日期文本进行子串。回答得好。是的,java.sql.Timestamp是一种攻击。所有旧的日期时间类(java.util.date、.Calendar、SimpleDataFormat)都是一团混乱。实际上注意到了hacky的本质:
由于Timestamp类和上面提到的java.util.Date类之间的差异,建议代码不要将时间戳值一般地作为java.util.Date的实例来查看。Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承。
噢,我没有看到这一点。在这种情况下,创建一个不从java.util.Date继承的SQL时间戳类更有意义。如果有必要,它可以在内部包装java.util.Date。
瞬间
具有分辨率,因此不会损失小数秒。java.sql.Timestamp类已扩展为现在提供和来自(即时)方法的
。因此,您可以使用现有的JDBC驱动程序。@Basil_Bourque,这是一个非常需要改进的地方;谢谢你指出这一点。但是,您可以在多大程度上使用现有的