java ssssss,在Java 7中将字符串日期转换为yyyy-MM-dd’T’HH:mm:ss.SSSSSS格式的字符串...

我有以下日期

2017-08-23-11.19.02.234850

它具有以下日期格式

yyyy-MM-dd-HH.mm.ss.SSSSSS

我要做的是将日期转换为yyyy-MM-dd'T'HH:mm:ss.SSSSSS

我有以下代码

public static void main(String[] args) {

String strDate ="2017-08-23-11.19.02.234850";

String dateFmt ="yyyy-MM-dd-HH.mm.ss.SSSSSS";

System.out.println("converted Date:" + convertDate(strDate, dateFmt));

}

public static String convertDate(String strDate, String format) {

SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);

sdf.setLenient(true);

try {

Date dateIn = sdf.parse(strDate);

return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS").format(dateIn);

}catch(ParseException e) {

e.printStackTrace();

}

return"";

}

结果是

converted Date: 2017-08-23T11:22:56.000850

输入日期2017-08-23-11.19.02.234850

转换日期2017-08-23T11:22:56.000850

看起来不一样,似乎java会舍入毫秒,如果我关闭宽大日期验证

sdf.setLenient(false);

我得到以下

java.text.ParseException: Unparseable date:"2017-08-23-11.19.02.234850"

at java.text.DateFormat.parse(Unknown Source)

at mx.santander.canonical.datamodel.enums.Main.convertDate(Main.java:74)

at mx.santander.canonical.datamodel.enums.Main.main(Main.java:66)

converted Date:

如何建立一个以正确的方式验证和转换日期字符串的函数?

编辑:

我添加了一个新功能以获得结果

/**

* Gets the ISO 8601 date str from string.

*

* @param strDate the str date

* @return the ISO 8601 date str from string

*/

private String getISO8601DateStrFromString (String strDate)  {

String responseISO8601Date ="";

if(strDate == null ||"".equals(strDate.trim())) {

return responseISO8601Date;

}

try {

String strDtWithoutNanoSec = strDate.substring(0, strDate.lastIndexOf("."));

String strDtNanoSec        = strDate.substring(strDate.lastIndexOf(".") + 1, strDate.length());

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss");

formatter.setLenient(false);

Date   date = formatter.parse(strDtWithoutNanoSec);

Timestamp t = new Timestamp(date.getTime());

t.setNanos(Integer.parseInt(strDtNanoSec));

DateFormat   df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'");

NumberFormat nf = new DecimalFormat("000000");

responseISO8601Date = df.format(t.getTime()) + nf.format(t.getNanos());

} catch (ParseException | StringIndexOutOfBoundsException | NumberFormatException e) {

String errorMsg = String.format("The date provided for conversion to ISO 8601 format [%s] is not correct", strDate);

System.out.println(errorMsg);

}

return responseISO8601Date;

}

我得到的是:

Uptadet date 2017-12-20T11:19:02.234850

.SSS是最大值(以毫秒为单位),范围是0至999

很好的阅读stackoverflow.com/questions/1712205/。请通过@Basil Bourque核对有关Java 9如何修复其实现的答案。

您正在使用麻烦的旧日期时间类,这些类现在已被遗留,由java.time类取代。

正如其他人已经提到的那样,您的要求不适合使用Date和SimpleDateFormat,因为它们仅支持毫秒,即秒的三个小数,其中您有六个小数(微秒)。因此,我们需要找到其他方法。无论如何,这基本上是一个好主意,因为Date和SimpleDateFormat早已过时,并且今天我们有更好的工具来完成这项工作。

我有两个建议给你。

java.time

即使在Java 7中,我也认为使用Java 8(即AKA JSR-310)附带的现代Java日期和时间API是一个好主意。你能做到吗?当然;将反向端口用于Java 6和7,ThreeTen反向端口。现代的API支持秒显示从0到9的十进制数,并且当您知道如何时,代码就很简单:

private static DateTimeFormatter inputParser

= DateTimeFormatter.ofPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS");

private static DateTimeFormatter outputFormatter

= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");

public static String convertDate(String strDate) {

return LocalDateTime.parse(strDate, inputParser)

.format(outputFormatter);

}

我正在使用自己的两种格式模式字符串。 convertDate("2017-08-23-11.19.02.234850")返回2017-08-23T11:19:02.234850。

有一个可能的简化:由于您要获取的格式符合ISO 8601,因此不需要显式格式化程序。现代类可以本地理解和生成ISO 8601格式,因此您可以使用:

return LocalDateTime.parse(strDate, inputParser).toString();

但是,如果秒的小数点恰巧以000结尾,则不会打印最后三个零。因此,即使在这种情况下也需要六位小数,请使用格式化程序。

正则表达式

如果您不想依赖外部库,甚至暂时不要依赖,直到升级到Java 8(或9)后,都可以使用正则表达式来完成工作:

return strDate

.replaceFirst("^(\\d{4}-\\d{2}-\\d{2})-(\\d{2})\\.(\\d{2})\\.(\\d{2}\\.\\d{6})$",

"$1T$2:$3:$4");

它不那么优雅,更难以阅读,并且无法提供使用正确的日期和时间API所获得的输入验证级别。除此之外,这是一种解决方法。

java.sql.Timestamp?

正如其他人所说,java.sql.Timestamp提供纳秒精度,因此可以保留您的日期时间。不过,将您的字符串解析为Timestamp并不是一件容易的事,因此我认为这样做不值得。 Usagi Miyanmoto正确地将Timestamp.valueOf()标识为要使用的方法,但是在您可以执行此操作之前,您必须更改格式,因此最终将更改格式两次,而不是一次。也许是三遍,因为Timestamp也不容易产生所需的ISO 8601格式。另外,您需要确定时间戳的时区,但是我认为您可以做到这一点而没有任何麻烦。

如果您需要保留日期时间,可以考虑使用Timestamp对象,但这又是一个过时的类。无论如何,仅凭格式重新格式化,我当然不会使用它。

您的代码中发生了什么?

SimpleDateFormat将234850理解为??毫秒,即234秒为850毫秒。因此,它为您的时间增加了234秒11:19:02。然后按要求将剩余的850毫秒打印在小数点后6位。

日期只能精确到毫秒。请改用timestamp-它的精度可以达到纳秒,这在您的情况下是可以预期的。

请参考此答案-精确到纳秒

时间戳API

A thin wrapper around java.util.Date that allows the JDBC API to

identify this as an SQL TIMESTAMP value. It adds the ability to hold

the SQL TIMESTAMP fractional seconds value, by allowing the

specification of fractional seconds to a precision of nanoseconds. A

Timestamp also provides formatting and parsing operations to support

the JDBC escape syntax for timestamp values.

Java的SimpleDateFormat不支持微秒模式。

java.util.Date格式SSSSSS:如果不是毫秒,则最后3位数字是多少?

您有几种选择:

手动处理微秒的解析和格式化

切换为使用Java 8,因为Time API支持模式的秒数(https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)

如果需要使用Java 7,请考虑将JODA Time用于日期时间逻辑。 JODA在其DateTimeFormat中支持秒级(http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html)

您得到的结果是预期的。在您的格式字符串中,使用了S。 S是毫秒,hat是千分之一秒,在这种情况下,S的数目对于解析而言并不重要。

输入字符串以11.19.02.234850结尾,最后一部分解释为整数值,并以毫秒为单位添加到日期和时间。即234.850秒。现在,如果将234秒添加到11:19:02,则它变为11:22:56,就像您得到的结果一样...

您不能创建可以将微秒解析为Date的SimpleDateFormat掩码,并且Date也不可以包含微秒的值。

您必须选择是否要使用Date,还是真的需要更好的毫秒级分辨率?

如果坚持使用Date,则应截断最后3个字符的字符串。

或者,您可以使用具有valueOf()方法的java.sql.Timestamp,并且使用SQL时间戳格式。

不幸的是,他和你的不完全一样(yyyy-[m]m-[d]d hh:mm:ss[.f...])...

另一种方法是用分隔符(如[-.])分割字符串,将其解析为整数,然后将整数与Timestamp()构造函数一起使用...

该Timestamp构造函数已被弃用。 并且由于某种原因而被弃用,因此跨时区是不可靠的。 所以我不想走那条路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值