2010-10-25 5 views
2

, что было бы самым простым способом, чтобы разобрать этот формат даты ниже в Java ?:разобрать этот формат даты в java?

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

я прочитал DateFormat API в Java и не мог найти метод, который принимает строку или даже этот тип формата даты как пареметр для разбора? Когда я подразумеваю под синтаксисом, я хочу, чтобы я хотел выделить «дату (день месяца и год)», «время» и «часовой пояс» в отдельные строковые объекты.

Заранее спасибо

+0

Я думаю, что вы ищете регулярное выражение или аналогичный ответ. Я предоставил второй ответ с конкретным рабочим циклом для этого конкретного решения ... – andersoj

ответ

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

Я звоню в веб-службу, которая отправляет мне дату календаря в формате 8601, а затем хочу, чтобы я показывал время, дату и часовой пояс отдельно. боль, которую я знаю, почему они не могут цветущие делать это со своей стороны, если это так, как они хотят отображать информацию. – jonney

+0

Также: я работал над reg ex сам, используя эти: private static final String REG_EX_DATE = "(. *) Т "; \t private static final String REG_EX_TIME = "T (. *) +"; \t приватная статическая конечная строка REG_EX_TIMEZONE = "+ | - (. *)"; – jonney

+0

im собирается попробовать выше код в любом случае приветствия для этого – jonney

2

Эта дата в ISO 8601 format. Вот a link to a parser specific to this format, который использует API-интерфейсы синтаксического анализа Java SimpleDateFormat.

+1

Привет, я думаю, что я diddnt объяснить себя правильно. Я получаю строку с тем же форматом, что и тот, который я опубликовал. то, что я хочу сделать, - это разделить строку на «дата (год, месяц и день)», «время» и «часовой пояс». – jonney

+0

После вызова parse() в вышеупомянутом API вы будете иметь объект Java java.util.Date. Этого должно быть достаточно, чтобы выяснить, как делать то, что вы хотите. Вам также нужно будет изучить API Java java.util.Calendar. – orangepips

+0

@jonney - в этом случае вы * можете * отделить строку, используя либо регулярное выражение, либо просто строковые фрагменты. Но это было бы очень хрупким. Я думаю, что использование календарной реализации будет относиться к вам гораздо лучше. – andersoj

0

Использование SimpleDateFormat, с рисунком в виде yyy-MM-dd'T'HH:mm:ss.SSSZ


Update SimpleDateFormat не будет работать с ISO 8601 формате даты. Вместо этого используйте вместо этого JodaTime. Он обеспечивает ISOChronology, который соответствует ISO 8601.

Краткое описание можно найти на SO.

+0

Это не сработает. SimpleDateFormat использует RFC 822 для форматирования часовых поясов, в то время как в примере есть строка часового пояса в соответствии с ISO 8601. Они несовместимы. – jarnbjo

+0

Почему «SimpleDateFormat не будет работать с форматом даты ISO 8601»? Смотрите мой ответ, что с ним не так? –

+0

@ Владимир Прудников, ваш форматировщик не будет учитывать разницу в часовом поясе. Как вы разбираете '+01: 00' в конце формата даты? –

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' в строке формата. –

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-вы можете сделать:

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); 
Смежные вопросы