我要格式化的字符串如下所示: String datetime =“9/1/10 11:34:35 AM”
以下SimpleDateFormat模式有效:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss");
Date d = sdf.parse(datetime);
System.out.println(d);
Output> [Wed Sep 01 11:34:35 CEST 2010]
但是我也需要解析AM / PM标记,当我将其添加到模式时,我会收到异常。
不起作用的模式:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss a");
我也尝试了同样的例外:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss aa");
例外:
java.text.ParseException: Unparseable date: "9/1/10 11:34:35 AM"
我在http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#text查看了API,但似乎无法找到我做错的地方。
有什么建议吗?
答案 0 :(得分:31)
一种可能性是您的默认Locale
具有不同的AM / PM符号。构建日期格式时,除非您确实要使用系统的默认Locale
,否则应始终提供Locale
,例如:
SimpleDateFormat sdf = new SimpleDateFormat("M/d/yy h:mm:ss a", Locale.US)
答案 1 :(得分:3)
我正在举例说明下面给出的日期,如果符合您的要求,请将格式化的日期打印成24小时格式。
String inputdate="9/1/10 11:34:35 AM";
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd/MM/yy hh:mm:ss aa",Locale.getDefault());
try {
System.out.println(""+new SimpleDateFormat("dd/MM/yy HH:mm:ss",Locale.getDefault()).format(simpleDateFormat.parse(inputdate)));
} catch (ParseException e) {
e.printStackTrace();
}
如果您还有任何疑问,请回复。感谢。
答案 2 :(得分:1)
现代回答:
String datetime = "9/1/10 11:34:35 AM";
LocalDateTime dt = LocalDateTime.parse(datetime,
DateTimeFormatter.ofPattern("M/d/yy h:mm:ss a", Locale.ENGLISH));
这将产生2010-09-01T11:34:35的LocalDateTime
。但要注意两位数的年份; DateTimeFormatter
将假设2000年到2099年。对于我的生日,这将是不正确的。
我们仍然需要提供语言环境。由于在英语以外的其他语言环境中,AM / PM标记很难用于实践,我认为Locale.ENGLISH
是一个相当安全的选择。请替换你自己的。
其他答案在2010年和2011年都是很好的答案。在2014年,上述内容已经有效,我更喜欢它。
答案 3 :(得分:1)
您可以使用 DateTimeFormatterBuilder
构建不区分大小写的解析器。由于日期时间解析/格式化类型(例如 DateTimeFormatter
、SimpleDateFormat
等)对 Locale
敏感,因此您应该始终使用具有此类类型的 Locale
。我使用 Locale.ENGLISH
是因为您的日期时间字符串有英文 AM/PM 标记。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/uu H:m:s a")
.toFormatter(Locale.ENGLISH);
//Test
Stream.of(
"9/1/10 11:34:35 AM",
"9/1/10 11:34:35 am",
"09/1/10 11:34:35 AM",
"9/01/10 11:34:35 Am"
).forEach(s -> System.out.println(LocalDateTime.parse(s, dtf)));;
}
}
输出:
2010-09-01T11:34:35
2010-09-01T11:34:35
2010-09-01T11:34:35
2010-09-01T11:34:35
从 modern date-time API 中了解有关 Trail: Date Time* 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
答案 4 :(得分:0)
如果您正在使用FreeMarker for Java并在此问题上弹出,请使用以下代码。我有这个问题,我的语言环境将AM / PM设置为DE。不知道为什么......
<#setting locale="en_US">
答案 5 :(得分:0)
关于Locale
的注意事项:
用于 AM/PM 的符号取决于 Locale
!
这会影响解析字符串,如果使用的 AM/PM 字段与预定义的符号不匹配,最终会导致错误。 (显然也会影响格式)
java.time.format.DateTimeFormatter
和 java.text.SimpleDateFormat
在创建时接受可选的 Locale
。如果没有给出。使用系统默认的。
警告:使用 DateTimeFormatter
AM/PM 标志的情况在解析时也是相关的,至少对于某些语言环境是这样。
例如,印度语言环境要求 AM/PM 标志为小写(am
、pm
),而其他一些语言环境(ROOT
、ITALY
、{ {1}}、US
) 只接受大写的 AM/PM。
这会抛出 GERMANY
DateTimeParseException: Text '2021-03-31 10:15:30 AM +05:30' could not be parsed at index 20
这导致 ZonedDateTime.parse("2021-03-31 10:15:30 AM +05:30",
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a Z",
new Locale("en", "IN")))
2021-03-31T10:15:30+05:30
使用 ZonedDateTime.parse("2021-03-31 10:15:30 am +05:30",
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a Z",
new Locale("en", "IN")))
、Locale.US
或 Locale.GERMANY
,结果反转。
注意:使用 Locale.ROOT
解析时 AM/PM 的大小写无关紧要(我不推荐使用它,我更喜欢 SimpleDateFormat
)