繁体   English   中英

从Oracle数据库转换具有AM / PM日期时间的字符串

[英]Conversion of string with AM/PM date-time, from Oracle database

我的时间戳形式为03-AUG-12 08.15.00.000000000 PM -05:00我无法在yyyy-MM-dd HH:mm:ss上获得表格中的String表示。

这是我的代码:

public static void convert() {

    String oldstring = "03-AUG-12 08.15.00.000000000 PM -05:00";
    Date date = null;
    try {
        date = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.S aa").parse(oldstring);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    String newstring = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    System.out.println(newstring);
}

基本上它是Oracle数据库中带有时区格式的时间戳。

你不能使用SimpleDateFormat来解析这样的字符串,至少没有一些限制:

  • 在Java 7之前不支持像-05:00(根据ISO 8601)的时区指示符。使用Java 7,您可以使用XXX模式对其进行解析。

  • 要正确解析月份名称,您应指定需要英语区域设置。

  • 毫秒(S)的模式解析无限数量的数字。 如果您的字符串包含“08.15.00.100000000”,SimpleDateFormat会将其解析为8:15:00和100000000ms,将预期值增加近28小时。 如果您确定该值始终为0,则可以忽略此问题。

如果您可以接受上一期并使用Java 7,那么您应该使用以下内容:

new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa XXX", Locale.ENGLISH)

像这样改变这一行:

        date = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa").parse(oldstring);

您需要使用小写h来解析AM / PM小时1-12。

TL;博士

DateTimeFormatter f = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ" ).toFormatter ().withLocale ( Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( "03-AUG-12 08.15.00.000000000 PM -05:00" , f );

对象,而不是字符串

你提到了Oracle。 从数据库检索数据时,请使用对象而不是字符串。 ResultSet询问java.sql.Timestamp对象。

java.sql.Timestamp ts = myResultSet.getTimestamp( … );

从麻烦的旧日期时间类转换为现代java.time类型。 查看旧类上添加的新方法,以便于转换为/从java.time转换。

Instant instant = ts.toInstant();

或者,最好是,如果使用JDBC 4.2或更高版本,并使用Java 8或更高版本,您可以通过ResultSet::getObject方法检索java.time.Instant

但是如果你必须解析一个字符串,请继续阅读。

避免旧的日期时间类

与最早版本的Java捆绑在一起的旧日期时间类很麻烦且令人困惑。 现在取代了java.time类。

纳秒

这一串零必须表示具有纳秒分辨率的小数秒,最多为小数部分的九位数。 旧的日期时间类只能处理几毫秒 ,但幸运的是,现代java.time类确实可以处理高达纳秒的分辨率。

使用java.time

定义格式模式以解析给定输入。 顺便说一句,您的数据格式不是最佳的; 将来,对表示日期时间值的字符串使用ISO 8601标准格式。

我们使用“构建器”来指定不区分大小写的解析。 英语月份名称的正确缩写是initial-cap, Aug ,但您的输入使用全部大写字母。

String pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ";
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( pattern );

告诉构建器实例化我们的格式化程序。 Locale确定(a)用于翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大小写,标点符号等问题的文化规范。

Locale l = Locale.US;
DateTimeFormatter f = fb.toFormatter ().withLocale ( l );

最后,将字符串解析为OffsetDateTime对象。

String input = "03-AUG-12 08.15.00.000000000 PM -05:00";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );

转储到控制台。 请注意我们的8 PM如何转换为20小时的24小时时钟值。

System.out.println ( "input: " + input + " | odt.toString(): " + odt );

输入:03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString():2012-08-03T20:15-05:00

时区与UTC偏移量 加上一组用于处理诸如夏令时(DST)等异常的规则。 如果需要,请应用ZoneId以获取ZonedDateTime

ZoneId z = ZoneId.of( “America/Montreal” );
ZonedDateTime zdt = odt.atZoneSameInstant( z );

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧日期时间类,如java.util.Date.Calendarjava.text.SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time。

要了解更多信息,请参阅Oracle教程 并搜索Stack Overflow以获取许多示例和解释。

大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,并进一步适应的AndroidThreeTenABP (见如何使用...... )。

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM