java 使用 AM/PM 日期时间转换字符串,来自 Oracle 数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10452210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Conversion of string with AM/PM date-time, from Oracle database
提问by Java Not Coffee
I have the timestamp in form of 03-AUG-12 08.15.00.000000000 PM -05:00
I am unable to get a String
representation in form on yyyy-MM-dd HH:mm:ss
.
我有形式的时间戳,03-AUG-12 08.15.00.000000000 PM -05:00
我无法获得String
形式上的表示yyyy-MM-dd HH:mm:ss
。
Here is my code :
这是我的代码:
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);
}
Basically it is a timestamp with timezone format from the Oracle database.
基本上它是来自 Oracle 数据库的时区格式的时间戳。
回答by jarnbjo
You can't use SimpleDateFormat to parse such a string, at least not without some limitations:
您不能使用 SimpleDateFormat 来解析这样的字符串,至少不是没有一些限制:
A time zone designator like -05:00 (according to ISO 8601) is not supported until Java 7. With Java 7 you can use the XXX pattern to parse it.
To parse the month name correctly, you should specify that you require an English locale.
The pattern for milliseconds (S) parses an unlimited number of digits. If your string contains "08.15.00.100000000", SimpleDateFormat would parse this as 8:15:00 and 100000000ms, adding almost 28 hours to the expected value. If you are sure that the value is always 0, you can ignore this problem.
直到 Java 7 才支持像 -05:00(根据 ISO 8601)这样的时区指示符。在 Java 7 中,您可以使用 XXX 模式来解析它。
要正确解析月份名称,您应该指定您需要英语语言环境。
毫秒 (S) 模式解析无限数量的数字。如果您的字符串包含“08.15.00.100000000”,SimpleDateFormat 会将其解析为 8:15:00 和 100000000 毫秒,从而使预期值增加近 28 小时。如果您确定该值始终为 0,则可以忽略此问题。
If you can accept the last issue and use Java 7, you should be using something like this:
如果您可以接受最后一个问题并使用 Java 7,那么您应该使用以下内容:
new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa XXX", Locale.ENGLISH)
new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa XXX", Locale.ENGLISH)
回答by Moritz Petersen
Change this line like this:
像这样改变这一行:
date = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa").parse(oldstring);
You need to use the lowercase h
which parses the AM/PM hours 1-12.
您需要使用h
解析 AM/PM 小时 1-12的小写字母。
回答by Basil Bourque
tl;dr
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 );
Objects, not strings
对象,而不是字符串
You mentioned Oracle. When retrieving data from a database, use objects rather than strings. Ask your ResultSet
for a java.sql.Timestamp
object.
你提到了甲骨文。从数据库中检索数据时,请使用对象而不是字符串。向你ResultSet
要一个java.sql.Timestamp
对象。
java.sql.Timestamp ts = myResultSet.getTimestamp( … );
Convert from the troublesome old date-time class to the modern java.time type. Look to new methods added on the old classes to facilitate conversion to/from java.time.
从麻烦的旧日期时间类转换为现代 java.time 类型。寻找添加在旧类上的新方法,以促进与 java.time 的转换。
Instant instant = ts.toInstant();
Or preferably, if using JDBC 4.2 or later, and using Java 8 or later, you may be able to retrieve an java.time.Instant
via the ResultSet::getObject
method.
或者最好,如果使用 JDBC 4.2 或更高版本,并且使用 Java 8 或更高版本,您可能能够java.time.Instant
通过该ResultSet::getObject
方法检索。
But if you must parse a string, read on.
但是,如果您必须解析字符串,请继续阅读。
Avoid old date-time classes
避免旧的日期时间课程
The old date-time classes bundled with the earliest versions of Java are troublesome and confusing. Now supplanted by the java.time classes.
与最早版本的 Java 捆绑在一起的旧日期时间类既麻烦又令人困惑。现在被 java.time 类取代。
Nanoseconds
纳秒
That bunch of zeros must represent a fraction of a second with nanosecondresolution, up to nine digits of a decimal fraction. The old date-time classes can handle only milliseconds, but fortunately the modern java.time classes can indeed handle a resolution up to nanoseconds.
那束零必须表示具有纳秒分辨率的几分之一秒,最多为十进制小数的九位数字。旧的日期时间类只能处理毫秒,但幸运的是现代 java.time 类确实可以处理高达纳秒的分辨率。
Using java.time
使用 java.time
Define a formatting pattern to parse the given input. By the way, your data's format is less than optimal; in the future, use ISO 8601standard formats for strings that represent date-time values.
定义格式化模式来解析给定的输入。顺便说一下,您的数据格式不是最佳的;将来,对表示日期时间值的字符串使用ISO 8601标准格式。
We use a “builder” in order to specify case-insensitive parsing. Proper abbreviation for a name of month in English is initial-cap, Aug
, but your input uses all-caps.
我们使用“构建器”来指定不区分大小写的解析。英文月份名称的正确缩写是 initial-cap, Aug
,但您的输入使用全大写。
String pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ";
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( pattern );
Tell the builder to instantiate our formatter. The Locale
to determines (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.
告诉构建器实例化我们的格式化程序。该Locale
原则来确定(一)一天的名称翻译,一个月的名称,这样,和(b)文化规范决定的缩写,大小写,标点符号,这样的问题的人类语言。
Locale l = Locale.US;
DateTimeFormatter f = fb.toFormatter ().withLocale ( l );
Finally, parse the string as an OffsetDateTime
object.
最后,将字符串解析为OffsetDateTime
对象。
String input = "03-AUG-12 08.15.00.000000000 PM -05:00";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
Dump to console. Note how our 8 PM is transformed into the 24-hour clockvalue of 20 hours.
转储到控制台。请注意我们的晚上 8 点如何转换为20 小时的24 小时制值。
System.out.println ( "input: " + input + " | odt.toString(): " + odt );
input: 03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString(): 2012-08-03T20:15-05:00
输入:03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString(): 2012-08-03T20:15-05:00
A time zoneis an offset-from-UTCplusa set of rules for handling anomalies such as Daylight Saving Time (DST). If desired, apply a ZoneId
to get a ZonedDateTime
.
一个时区是一个偏移从-UTC加上一组用于处理异常,如夏令时(DST)规则。如果需要,应用 aZoneId
以获得ZonedDateTime
.
ZoneId z = ZoneId.of( “America/Montreal” );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧日期时间类,例如java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to java.time.
现在处于维护模式的Joda-Time项目建议迁移到 java.time。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backportand further adapted to Androidin ThreeTenABP(see How to use…).
大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植,并进一步用于安卓在ThreeTenABP(见如何使用......)。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
,等。