Java 格式 yyyy-MM-dd'T'HH:mm:ss.SSSz 转 yyyy-mm-dd HH:mm:ss

Posted

技术标签:

【中文标题】Java 格式 yyyy-MM-dd\'T\'HH:mm:ss.SSSz 转 yyyy-mm-dd HH:mm:ss【英文标题】:Java format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ssJava 格式 yyyy-MM-dd'T'HH:mm:ss.SSSz 转 yyyy-mm-dd HH:mm:ss 【发布时间】:2013-03-21 18:02:08 【问题描述】:

我正在尝试将 yyyy-MM-dd'T'HH:mm:ss.SSSz 格式的日期格式化为 yyyy-mm-dd HH:mm:ss,这应该很容易,但我无法获得它可以工作。

必须解析的日期格式为:2012-10-01T09:45:00.000+02:00 现在我使用这个简单的日期格式化程序来格式化它:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz", Locale.FRANCE);

但这给出了类似于 2012-10-01T09:45:00.000UTC+00:00 的输出。

我也尝试使用“yyyy-MM-dd'T'HH:mm:ss.SSSZ”作为模式和“yyyy-MM-ddHH:mm:ss”。后者以 2012-10-01T09:45:00 close 的形式返回日期,但还没有。

我认为将 T 去掉会有点混乱,并且会无缘无故地产生开销,那么格式化这些日期的正确方法是什么?

为了说明我想将 2012-10-01T09:45:00.000+02:00 转换为 2012-10-01 09:45:00

干杯!

【问题讨论】:

子字符串比转换到/从日期对象更快/更简单。您只需将原始字符串分成两个子字符串(固定偏移量),然后用空格连接在一起。 这是为什么呢?我一次可能会解析多达 100 多个日期。 您不认为两个带有硬编码偏移量的子字符串操作加上几个连接操作会比构造和执行两个日期格式化程序更快吗? 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleTextFormat 现在是 legacy,被 java.time 类取代。 【参考方案1】:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(time);
String formattedTime = output.format(d);

这行得通。您必须使用两种 SimpleDateFormat,一种用于输入,一种用于输出,但它会为您提供您想要的。

【讨论】:

它在开始时附加 12...我预计日期 02/05/2017 但它给了我 122/05/2017【参考方案2】:

java.time

针对这个问题,我们有新技术:Java 8 及更高版本中内置的 java.time 框架。

您的输入字符串采用标准 ISO 8601 格式。默认情况下,该标准在 java.time 类中用于解析/生成日期时间值的文本表示。

OffsetDateTime odt = OffsetDateTime.parse( "2012-10-01T09:45:00.000+02:00" );

您的问题建议您要截断一整秒。

OffsetDateTime odtTruncatedToWholeSecond = odt.truncatedTo( ChronoUnit.SECONDS );

您似乎想省略偏移量和时区信息。预定义的格式化程序 DateTimeFormatter.ISO_LOCAL_DATE_TIME 会这样做。

显然你想在中间使用一个空格而不是标准的T。您可以为此定义自己的格式化程序,但我只需进行字符串操作以将T 替换为空格。

String output = odtTruncatedToWholeSecond.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " );

简单的字符串操作

正如问题中的 cmets 所建议的那样,严格来说,您可以通过仅使用字符串而不转换为任何日期时间对象来实现您的目标。但我在这里提供此答案,假设您可能有其他业务逻辑来处理这些日期时间值。



关于java.time

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

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

Java SE 8Java SE 9 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6Java SE 7 ThreeTen-Backport 中的大部分 java.time 功能都向后移植到 Java 6 和 7。 Android 更高版本的 android 捆绑包实现 java.time 类。 对于早期的 Android,ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。

【讨论】:

仅适用于 java 8 或更高版本 @Sangram 实际上,不,不仅仅是 Java 8。ThreeTen-Backport 项目中的大部分 java.time 功能都向后移植到 Java 6 和 Java 7,并在 @ 中进一步适应了 Android 987654350@项目。【参考方案3】:

Gooye 如果可以在您的项目中使用 Joda Time,那么此代码对我有用:

String dateStr = "2012-10-01T09:45:00.000+02:00";
String customFormat = "yyyy-MM-dd HH:mm:ss";

DateTimeFormatter dtf = ISODateTimeFormat.dateTime();
LocalDateTime parsedDate = dtf.parseLocalDateTime(dateStr);

String dateWithCustomFormat = parsedDate.toString(DateTimeFormat.forPattern(customFormat));
System.out.println(dateWithCustomFormat);

【讨论】:

白白添加更多依赖。它存在于 JDK 中,请参阅 Chris Tate 回答 我认为它适用于 java 8,不适用于 java 7 或更低版本。 @Sam,它适用于任何 java 版本,因为它使用 joda-time 库。只需将其导入您的项目并导入所需的依赖项即可。【参考方案4】:

我试图格式化从 JSON 响应接收到的日期字符串,例如2016-03-09T04:50:00-0800 至 yyyy-MM-dd。所以这就是我尝试过的方法,它有效并帮助我将格式化的日期字符串分配给日历小部件。

String DATE_FORMAT_I = "yyyy-MM-dd'T'HH:mm:ss";
String DATE_FORMAT_O = "yyyy-MM-dd";


SimpleDateFormat formatInput = new SimpleDateFormat(DATE_FORMAT_I);
SimpleDateFormat formatOutput = new SimpleDateFormat(DATE_FORMAT_O);

Date date = formatInput.parse(member.getString("date"));
String dateString = formatOutput.format(date);

这行得通。谢谢。

【讨论】:

这个答案没有解决问题的细节。它复制了3-year-old accepted answer 的想法。所以我看不出有任何价值。很高兴看到您想参与 Stack Overflow。但您的答案必须针对问题的具体情况,不能重复。【参考方案5】:
String dateStr = "2016-09-17T08:14:03+00:00";
String s = dateStr.replace("Z", "+00:00");
s = s.substring(0, 22) + s.substring(23);
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
Timestamp createdOn = new Timestamp(date.getTime());
mcList.setCreated_on(createdOn);

Java 7 根据 ISO 8601 添加了对时区描​​述符的支持。这可以在 Java 7 中使用。

【讨论】:

【参考方案6】:

如果你真的要快(我不相信你这样做):

char[] chars = sourceDate.toCharArray();
chars[10] = ' ';
String targetDate = new String(chars, 0, 19);

【讨论】:

【参考方案7】:

试试这个

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

SimpleDateFormat output = new SimpleDateFormat("yyyyMMddHHmmss");

Date d = sdf.parse("2021-09-23T22:05:18.884Z");

String formattedTime = output.format(d);

System.out.println(formattedTime);

结果:20210923220518

【讨论】:

请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中做得更好。 我试过了,你鼓励我这样做。从您的代码中,我预计 20210922072818 因为原始字符串是 UTC 并且我的时区比 UTC 早 2 小时。我得到了2021092650509884。两位数太多,月中日、时、分、秒都不正确。 @OleV.V.我已经编辑了我的代码,现在您将从中获得预期的结果。问题是您期望从这种格式 yyyyMMddHHmmss 获得的结果格式。 更接近。它仍然没有给我我所在时区的时间。【参考方案8】:

我有一个案例,我将遗留 DB2 z/os 数据库时间戳(格式为:"yyyy-MM-dd'T'HH:mm:ss.SSSZ")转换为由我们的 Spring/Hibernate 实体处理的 SqlServer 2016 datetime2(格式为:"yyyy-MM-dd HH:mm:ss.SSS)字段管理器实例(在本例中为 OldRevision 表)。在Class中,我将日期定义为java.util类型,并以正常方式编写setter和getter。然后,在处理数据时,我处理与此问题相关的数据的代码如下所示:

OldRevision revision = new OldRevision();
String oldRevisionDateString= oldRevisionData.getString("originalRevisionDate", "");
Date oldDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ");
oldDateFormat.parse(oldRevisionDateString);
SimpleDateFormat newDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
newDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
Date finalFormattedDate= newDateFormat.parse(newDateFormat.format(oldDateFormat));
revision.setOriginalRevisionDate(finalFormattedDate);
em.persist(revision);

做同样情况的更简单的方法是:

SimpleDateFormat newDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
newDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
revision.setOriginalRevisionDate(
        newDateFormat.parse(newDateFormat.format(
                new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ")
                        .parse(rs.getString("originalRevisionDate", "")))));

【讨论】:

以上是关于Java 格式 yyyy-MM-dd'T'HH:mm:ss.SSSz 转 yyyy-mm-dd HH:mm:ss的主要内容,如果未能解决你的问题,请参考以下文章

java如何实现各国时间格式转换成yyyy-MM-dd HH:mm:ss时间格式?

Java 格式 yyyy-MM-dd'T'HH:mm:ss.SSSz 转 yyyy-mm-dd HH:mm:ss

Java如何获取Date类型且格式为yyyy-mm-dd的日期数据?

java中,Date如何格式化为“yyyy-MM-dd”格式Date,并可按需求格式输出!(java.util.Date)

java中日期格式的转换,String类型的如:03/Jun/2013这种格式的,怎样转换成yyyy-mm-dd格式的?

在 Java 中,如何将任何格式的数字日期(例如 dd/MM/yyyy)转换为任何其他数字格式(例如 yyyy-MM-dd)? [复制]