例如:我有一个字符串,如
2011-09-27T07:04:21.97-05:00
,该字符串的日期格式为yyyy-MM-dd'T'HH:mm:ss.SSS
。在这里,当我将字符串(
2011-09-27T07:04:21.97-05:00
)传递给一个方法时,我想找出这个日期格式,该方法将返回格式(yyyy-MM-dd'T'HH:mm:ss.SSS
),然后我将根据我的要求格式化给定的日期字符串(如yy-mm--dd或mm/dd/yyyy
)。请问如何实现?
2011-09-27T07:04:21.97-05:00
,该字符串的日期格式为yyyy-MM-dd'T'HH:mm:ss.SSS
。2011-09-27T07:04:21.97-05:00
)传递给一个方法时,我想找出这个日期格式,该方法将返回格式(yyyy-MM-dd'T'HH:mm:ss.SSS
),然后我将根据我的要求格式化给定的日期字符串(如yy-mm--dd或mm/dd/yyyy
)。import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NewClass {
private static final String[] formats = {
"yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd HH:mm:ss",
"MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy'T'HH:mm:ss.SSS'Z'",
"MM/dd/yyyy'T'HH:mm:ss.SSSZ", "MM/dd/yyyy'T'HH:mm:ss.SSS",
"MM/dd/yyyy'T'HH:mm:ssZ", "MM/dd/yyyy'T'HH:mm:ss",
"yyyy:MM:dd HH:mm:ss", "yyyyMMdd", };
/*
* @param args
*/
public static void main(String[] args) {
String yyyyMMdd = "20110917";
parse(yyyyMMdd);
}
public static void parse(String d) {
if (d != null) {
for (String parse : formats) {
SimpleDateFormat sdf = new SimpleDateFormat(parse);
try {
sdf.parse(d);
System.out.println("Printing the value of " + parse);
} catch (ParseException e) {
}
}
}
}
}
Z
作为文字字面量。它是一个偏移量,需要解析为这样,否则会得到错误的结果。2020年的一个评论是:我们不应该再使用 Date
和 SimpleDateFormat
。这些类设计很差,而且已经过时了。 - Ole V.V.你可以像这样做,我不知道是否好用,但可以试试:
首先创建SimpleDateFormat对象。
SimpleDateFormt sdf = new SimpleDateFormat("yyyy-MM-dd 'T' HH:mm:ss.SSS");
现在当检查日期是否可以按照此格式解析时,根据您的格式进行修改。
try{
Date date = sdf.parse(yourdate);
sdf.applyPattern("yy-mm--dd or mm/dd/yyyy");
String dateformat = sdf.format(date);
}catch(Exception ex) { // here forgot the exact exception class Parse exception was used
// do something here
}
更新的帖子:
http://regexlib.com/DisplayPatterns.aspx?cattabindex=4&categoryId=5&AspxAutoDetectCookieSupport=1
DateFormat.parse()
将任意格式的字符串(即您不知道其格式的字符串)解析为日期?那么您需要处理如何处理 01-02-03
(是2003年1月2日?还是2003年2月1日等等)等问题。SimpleDateFormat
解析方法的情况下确定模式。通过使用正则表达式,您可以从日期字符串值中获取任何日期模式。package com.utility.utils.modelmapper.datetime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class DateParser {
private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {
{
put("^\\d{8}$", "yyyyMMdd");
put("^\\d{12}$", "yyyyMMddHHmm");
put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
put("^\\d{14}$", "yyyyMMddHHmmss");
put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
put("^\\d{4}-\\d{1,2}-\\d{1,2}T\\d{1,2}:\\d{2}:\\d{2}\\.\\d{2}[-+]\\d{2}:\\d{2}$", "yyyy-MM-dd'T'HH:mm:ss.SSS");
}
};
/**
* To Determine the pattern by the string date value
*
* @param dateString
* @return The matching SimpleDateFormat pattern, or null if format is unknown.
*/
public static String determineDateFormat(String dateString) {
for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
if (dateString.matches(regexp) || dateString.toLowerCase().matches(regexp)) {
return DATE_FORMAT_REGEXPS.get(regexp);
}
}
return null;
}
public static void main(String[] args) {
parse("2011-09-27T07:04:21.97-05:00"); //here is your value
parse("20110917");
parse("01/02/2018");
parse("02-01-2018 06:07:59");
parse("02 January 2018");
}
public static void parse(String value) {
if (value != null) {
String format = determineDateFormat(value);
if (format != null) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
Date date = sdf.parse(value);
System.out.println(String.format("Format : %s | Value : %s | Parsed Date : %s", value, date, format));
} catch (ParseException e) {
// Failed the execution
}
}
}
}
}
该类的控制台输出:
Format : 2011-09-27T07:04:21.97-05:00 | Value : Tue Sep 27 07:04:21 LINT 2011 | Parsed Date : yyyy-MM-dd'T'HH:mm:ss.SSS
Format : 20110917 | Value : Sat Sep 17 00:00:00 LINT 2011 | Parsed Date : yyyyMMdd
Format : 01/02/2018 | Value : Tue Jan 02 00:00:00 LINT 2018 | Parsed Date : MM/dd/yyyy
Format : 02-01-2018 06:07:59 | Value : Tue Jan 02 06:07:59 LINT 2018 | Parsed Date : dd-MM-yyyy HH:mm:ss
Format : 02 January 2018 | Value : Tue Jan 02 00:00:00 LINT 2018 | Parsed Date : dd MMMM yyyy
SimpleDateFormat
类。至少不要将其作为第一选择。而且不要毫无保留地使用它。今天,我们有更好的选择——java.time
,这是现代Java日期和时间API,以及它的DateTimeFormatter
。否则,这是一个创造性的解决方案。 - Ole V.V.SimpleDateFormat
如何工作,而是看问题所在——它是关于获取日期格式的。我只是使用 SimpleDateFormat
来展示它实际上获取了正确的格式。在获取到正确的格式后,可以使用任何你喜欢的方式。 - Vinit Solanki您可以尝试使用dateparser。
它可以自动识别任何字符串,并将其正确快速地解析为日期、日历、本地日期时间、偏移日期时间(1us~1.5us
)。
它不基于任何自然语言分析器
、SimpleDateFormat
或者regex.Pattern
。
使用它,您无需准备任何适当的模式,如yyyy-MM-dd'T'HH:mm:ss'Z'
或MM/dd/yyyy HH:mm:ss
等:
Date date = DateParserUtils.parseDate("2015-04-29T10:15:00.500+0000");
Calendar calendar = DateParserUtils.parseCalendar("2015-04-29T10:15:00.500Z");
LocalDateTime dateTime = DateParserUtils.parseDateTime("2015-04-29 10:15:00.500 +00:00");
它比循环尝试多个SimpleDateFormat
具有更好的性能。
请享用。
我们不能为任何日期时间格式都这样做。有成千上万种格式,我们不可能都知道(明天会有人发明新的),有些看起来非常相似,我们无法确定我们得到了哪个。
我建议对于大多数目的,您需要解析字符串,但不需要知道格式模式。在很多情况下,包括您问题中的示例2011-09-27T07:04:21.97-05:00
,我们不需要指定模式(您的字符串与DateTimeFormatter.ISO_OFFSET_DATE_TIME
匹配)。
自从Java 8于2014年发布以来(即使仍在使用Java 6或7),请使用现代Java日期和时间API java.time 处理日期和时间。
我正在定义一个格式化程序数组,用于处理我们想要处理的格式。请替换为您自己的设置。
private static final DateTimeFormatter[] formatters = {
DateTimeFormatter.ISO_OFFSET_DATE_TIME,
DateTimeFormatter.RFC_1123_DATE_TIME,
new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter(),
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(Locale.US),
DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm")
.withZone(ZoneId.of("America/Los_Angeles"))
};
以下方法会依次尝试各种格式化方式,直到找到可用的为止:
private static OffsetDateTime parse(String dateTimeString) {
for (DateTimeFormatter formatter : formatters) {
try {
return ZonedDateTime.parse(dateTimeString, formatter)
.toOffsetDateTime();
} catch (DateTimeParseException dtpe) {
// Ignore, try next formatter
}
}
throw new IllegalArgumentException("String " + dateTimeString + " could not be parsed");
}
让我们尝试一些不同的字符串:
String[] dateTimeStrings = {
"2011-09-27T07:04:21.97-05:00",
"20110917",
"2012-07-04",
"12/27/2014 23:45",
"Mon, 12 Nov 2018 01:32:10 GMT",
"July 29, 2015 at 10:19:36 AM EDT",
};
for (String dts : dateTimeStrings) {
try {
System.out.format("%32s -> %s%n", dts, parse(dts));
} catch (IllegalArgumentException iae) {
System.out.format("%32s -> %s%n", dts, iae);
}
}
输出为:
2011-09-27T07:04:21.97-05:00 -> 2011-09-27T07:04:21.970-05:00
20110917 -> java.lang.IllegalArgumentException: String 20110917 could not be parsed
2012-07-04 -> 2012-07-04T00:00Z
12/27/2014 23:45 -> 2014-12-27T23:45-08:00
Mon, 12 Nov 2018 01:32:10 GMT -> 2018-11-12T01:32:10Z
July 29, 2015 at 10:19:36 AM EDT -> 2015-07-29T10:19:36-04:00
解析多种格式的日期和时间的技术包括:
[uuuu][uu]
将解析四位或两位年份(2021 或只有 21)。注意歧义。经典例子是两种格式MM-dd-yyyy
和dd-MM-yyyy
。如果我们得到一个字符串03-09-2020
,就无法确定它是3月9日还是9月3日。更糟糕的是,02-05-07
可能是yy-MM-dd
、dd-MM-yy
、MM-dd-yy
甚至更多的可能性。因此,请确保不要包含可能将同一字符串解析为不同结果的两个(或更多)格式化程序。
HH:mm:ss.SSS => ([0-2]{1,}[0-9]{1,})(:)([0-5]{1,}[0-9]{1,})(:)([0-5]{1,}[0-9]{1,})(.)([0-9]{1,3})
yyyy-mm-dd => ([0-9]{4})(-)([0-1]{1,}[0-9]{1,})(-)([0-3]{1,}[0-9]{1,})