Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

¿cuál sería la forma más fácil de analizar este formato de fecha a continuación en java:?

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

he leído la API DateFormat en Java y no podía encontrar un método que toma una cadena o incluso este tipo de formato de fecha como Paremeter para analizar? Cuando me refiero por análisis sintáctico Quiero decir que yo quiero para extraer la "fecha (día, mes y año)", "tiempo" y "zona horaria" en objetos de cadena separados.

Gracias de antemano

¿Fue útil?

Solución

Otra respuesta, ya que parece estar centrado en simplemente rasgando el String aparte (no es una buena idea, en mi humilde opinión.) Supongamos que la cadena es válida ISO8601. Se puede asumir que será siempre en la forma que usted cita, o es sólo válida 8601? En este último caso, usted tiene que hacer frente a un montón de escenarios como estos chicos hicieron .

La expresión regular que llevaron a cabo para validar alternativas es 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)?)?)?)?$ 

Me Encontrar la manera de desentrañar los grupos de captura correctas hace mareado. Sin embargo, el siguiente trabajo para su caso específico:

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");
    }
  }
}

Otros consejos

Si usted está haciendo algo no trivial con fechas y horas, recomienda el uso de JodaTime . Ver esta extensa discusión SO , incluyendo ISO8601 . Ver también " ¿Debo usar nativa de datos / tiempo ... ".

El siguiente es un fragmento de código de ejemplo, tomado de este ejemplo , si desea utilizar el 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 );        
}

Esta fecha está en formato ISO 8601 . Aquí es un enlace a un programa de análisis específico para este formato que utiliza el Java API SimpleDateFormat analizar internamente.

Usted debe estar utilizando SimpleDateFormat ,

aquí y aquí para empezar

Se puede utilizar javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation) ( API Docs ). El XMLGregorianCalendar regresado le da acceso a todos los campos separados.

SimpleDateFormat , con el patrón como yyy-MM-dd'T'HH:mm:ss.SSSZ


Actualizar SimpleDateFormat no funcionará con la norma ISO 8601 formato de fecha. utilizar más bien, JodaTime lugar. Proporciona ISOChronology que cumpla con la norma ISO 8601 .

ejemplo Breve se puede encontrar en .

La solución más sencilla es la siguiente:

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);

Esto imprimirá Sat Sep 18 11:00:00 CEST 2010.

Si está utilizando Java 7 o anterior se puede hacer referencia a esta después .

Si está utilizando Java 8 que podría hacer:

    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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top