2010-10-25 57 views
2

這將是在Java?:下面解析此日期格式的最簡單的方法在java中解析這種類型的日期格式?

2010-09-18T10:00:00.000+01:00 

我在java中讀取日期格式API,但沒有找到,需要一個字符串,甚至這種類型的日期格式的方法一個paremeter解析?當我的意思是解析我的意思是我想提取「日期(日月和年)」,「時間」和「時區」到單獨的字符串對象。

在此先感謝

+0

我認爲你正在尋找一個正則表達式或類似的答案。我爲這個特定的解決方案提供了一個具體的,工作正則表達式的第二個答案... – andersoj 2010-10-25 13:07:44

回答

4

另一個答案,因爲你似乎集中在簡單撕裂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"); 
    } 
    } 
} 
+0

我打電話給一個Web服務,它以8601格式向我發送日曆事件日期,然後讓我單獨顯示時間,日期和時區。一個痛苦,我知道的,爲什麼不可能他們綻放從自己身邊這樣做,如果這就是他們想要顯示的信息 – jonney 2010-10-25 13:12:55

+0

另外:我正在使用這些部件的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

+0

即時將要嘗試上述代碼無論如何幹杯 – jonney 2010-10-25 13:32:32

2

此日期爲ISO 8601 format。這裏是a link to a parser specific to this format,它在內部使用Java SimpleDateFormat解析API。

+1

嗨,我想我沒有正確解釋自己。我得到一個與我發佈的格式相同的字符串。我想要做的是將字符串分成「日期(年,月,日)」,「時間」和「時區」。 – jonney 2010-10-25 11:14:51

+0

一旦您在上述API中調用parse(),您將擁有一個Java java.util.Date對象。這應該足以讓你瞭解如何做你想做的事。您還需要查看Java java.util.Calendar類API。 – orangepips 2010-10-25 11:35:53

+0

@jonney - 在這種情況下,你*可以*使用正則表達式或簡單的字符串切片來分隔字符串。但那會非常脆弱。我認爲使用日曆實施會更好地對待你。 – andersoj 2010-10-25 12:53:53

0

使用SimpleDateFormat,與圖案爲yyy-MM-dd'T'HH:mm:ss.SSSZ


更新的SimpleDateFormat不會與ISO 8601的日期格式工作。取而代之的是使用JodaTime。它提供符合ISO 8601的ISOChronology

簡要示例可在SO上找到。

+0

這是行不通的。 SimpleDateFormat使用RFC 822對時區進行格式設置,而示例中有一個根據ISO 8601的時區字符串。這些不兼容。 – jarnbjo 2010-10-25 11:35:41

+0

爲什麼「SimpleDateFormat不能使用ISO 8601日期格式」?看我的答案,它有什麼問題? – 2014-06-12 10:17:56

+0

@Vladimir Prudnikov,你的格式化程序不會考慮時區差異。如何在日期格式結尾解析「+01:00」? – 2014-06-12 17:57:31

3

如果你正在做日期和時間不平凡的事情,建議使用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);   
} 
+0

您不必在時區之前插入GMT。你只需要格式字符串中的'XXX'而不是'z'。 – 2014-06-12 10:19:39

0

您可以使用javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)API docs)。返回的XMLGregorianCalendar使您可以訪問所有單獨的字段。

0

最簡單的方法是這樣的:

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

0

如果您使用的是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);