在java中解析这种类型的日期格式?
这将是在Java?:下面解析此日期格式的最简单的方法在java中解析这种类型的日期格式?
2010-09-18T10:00:00.000+01:00
我在java中读取日期格式API,但没有找到,需要一个字符串,甚至这种类型的日期格式的方法一个paremeter解析?当我的意思是解析我的意思是我想提取“日期(日月和年)”,“时间”和“时区”到单独的字符串对象。
在此先感谢
另一个答案,因为你似乎集中在简单撕裂String
分开(不是一个好主意,恕我直言。)让我们假设字符串是有效的ISO8601。你能否认为它会总是以你引用的形式出现,还是仅仅是有效的8601?如果是后者,你必须应对一系列场景,如these guys did。
他们想出了验证8601层的替代品的正则表达式是:
^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])
(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])
((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?
([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$
搞清楚如何梳理出正确的捕捉组让我头昏眼花。然而,下面就为您的特定情况下工作:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regex8601
{
static final Pattern r8601 = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})T((\\d{2}):"+
"(\\d{2}):(\\d{2})\\.(\\d{3}))((\\+|-)(\\d{2}):(\\d{2}))");
//2010-09-18T10:00:00.000+01:00
public static void main(String[] args)
{
String thisdate = "2010-09-18T10:00:00.000+01:00";
Matcher m = r8601.matcher(thisdate);
if (m.lookingAt()) {
System.out.println("Year: "+m.group(1));
System.out.println("Month: "+m.group(2));
System.out.println("Day: "+m.group(3));
System.out.println("Time: "+m.group(4));
System.out.println("Timezone: "+m.group(9));
} else {
System.out.println("no match");
}
}
}
我打电话给一个Web服务,它以8601格式向我发送日历事件日期,然后让我单独显示时间,日期和时区。一个痛苦,我知道的,为什么不可能他们绽放从自己身边这样做,如果这就是他们想要显示的信息 – jonney 2010-10-25 13:12:55
另外:我正在使用这些部件的REG前自己: 私有静态最后弦乐REG_EX_DATE =“(。 *)T“; \t private static final String REG_EX_TIME =“T(。*)+”; \t private static final String REG_EX_TIMEZONE =“+ | - (。*)”; – jonney 2010-10-25 13:13:20
即时将要尝试上述代码无论如何干杯 – jonney 2010-10-25 13:32:32
此日期为ISO 8601 format。这里是a link to a parser specific to this format,它在内部使用Java SimpleDateFormat解析API。
嗨,我想我没有正确解释自己。我得到一个与我发布的格式相同的字符串。我想要做的是将字符串分成“日期(年,月,日)”,“时间”和“时区”。 – jonney 2010-10-25 11:14:51
一旦您在上述API中调用parse(),您将拥有一个Java java.util.Date对象。这应该足以让你了解如何做你想做的事。您还需要查看Java java.util.Calendar类API。 – orangepips 2010-10-25 11:35:53
@jonney - 在这种情况下,你*可以*使用正则表达式或简单的字符串切片来分隔字符串。但那会非常脆弱。我认为使用日历实施会更好地对待你。 – andersoj 2010-10-25 12:53:53
使用SimpleDateFormat,与图案为yyy-MM-dd'T'HH:mm:ss.SSSZ
更新的SimpleDateFormat不会与ISO 8601的日期格式工作。取而代之的是使用JodaTime。它提供符合ISO 8601的ISOChronology。
简要示例可在SO上找到。
这是行不通的。 SimpleDateFormat使用RFC 822对时区进行格式设置,而示例中有一个根据ISO 8601的时区字符串。这些不兼容。 – jarnbjo 2010-10-25 11:35:41
为什么“SimpleDateFormat不能使用ISO 8601日期格式”?看我的答案,它有什么问题? – 2014-06-12 10:17:56
@Vladimir Prudnikov,你的格式化程序不会考虑时区差异。如何在日期格式结尾解析“+01:00”? – 2014-06-12 17:57:31
如果你正在做日期和时间不平凡的事情,建议使用JodaTime。见this extensive SO discussion,包括ISO8601。另请参阅"Should I use native data/time..."。
下面是一个示例代码片段,摘自this example,如果您要使用JDK SimpleDateFormat
。
// 2004-06-14T19:GMT20:30Z
// 2004-06-20T06:GMT22:01Z
// http://www.cl.cam.ac.uk/~mgk25/iso-time.html
//
// http://www.intertwingly.net/wiki/pie/DateTime
//
// http://www.w3.org/TR/NOTE-datetime
//
// Different standards may need different levels of granularity in the date and
// time, so this profile defines six levels. Standards that reference this
// profile should specify one or more of these granularities. If a given
// standard allows more than one granularity, it should specify the meaning of
// the dates and times with reduced precision, for example, the result of
// comparing two dates with different precisions.
// The formats are as follows. Exactly the components shown here must be
// present, with exactly this punctuation. Note that the "T" appears literally
// in the string, to indicate the beginning of the time element, as specified in
// ISO 8601.
// Year:
// YYYY (eg 1997)
// Year and month:
// YYYY-MM (eg 1997-07)
// Complete date:
// YYYY-MM-DD (eg 1997-07-16)
// Complete date plus hours and minutes:
// YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
// Complete date plus hours, minutes and seconds:
// YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
// Complete date plus hours, minutes, seconds and a decimal fraction of a
// second
// YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
// where:
// YYYY = four-digit year
// MM = two-digit month (01=January, etc.)
// DD = two-digit day of month (01 through 31)
// hh = two digits of hour (00 through 23) (am/pm NOT allowed)
// mm = two digits of minute (00 through 59)
// ss = two digits of second (00 through 59)
// s = one or more digits representing a decimal fraction of a second
// TZD = time zone designator (Z or +hh:mm or -hh:mm)
public static Date parse(String input) throws java.text.ParseException
{
//NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
//things a bit. Before we go on we have to repair this.
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
//this is zero time so we need to add that TZ indicator for
if (input.endsWith("Z")) {
input = input.substring(0, input.length() - 1) + "GMT-00:00";
} else {
int inset = 6;
String s0 = input.substring(0, input.length() - inset);
String s1 = input.substring(input.length() - inset, input.length());
input = s0 + "GMT" + s1;
}
return df.parse(input);
}
您不必在时区之前插入GMT。你只需要格式字符串中的'XXX'而不是'z'。 – 2014-06-12 10:19:39
您可以使用javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)
(API docs)。返回的XMLGregorianCalendar使您可以访问所有单独的字段。
最简单的方法是这样的:
Date date = null;
SimpleDateFormat isoFormatWithMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
try {
date = isoFormatWithMillis.parse("2010-09-18T10:00:00.000+01:00");
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
这将打印Sat Sep 18 11:00:00 CEST 2010
。
如果您使用的是Java 7或更早的版本,可以参考此post。
如果您使用的是Java 8,你可以这样做:
DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
TemporalAccessor accessor = timeFormatter.parse("2015-10-27T16:22:27.605-07:00");
Date date = Date.from(Instant.from(accessor));
System.out.println(date);
我认为你正在寻找一个正则表达式或类似的答案。我为这个特定的解决方案提供了一个具体的,工作正则表达式的第二个答案... – andersoj 2010-10-25 13:07:44