Pergunta

Eu tenho uma string de data e quero analisá -la para a data normal Use a API de data java, a seguir é o meu código:

public static void main(String[] args) {
    String date="2010-10-02T12:23:23Z";
    String pattern="yyyy-MM-ddThh:mm:ssZ";
    SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    try {
        Date d=sdf.parse(date);
        System.out.println(d.getYear());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

No entanto, recebi uma exceção: java.lang.IllegalArgumentException: Illegal pattern character 'T'

Então, eu me pergunto se tenho que dividir a corda e analisá -la manualmente?

BTW, eu tentei adicionar um único personagem de cotação em ambos os lados do T:

String pattern="yyyy-MM-dd'T'hh:mm:ssZ";

Também não funciona.

Foi útil?

Solução

Atualização para Java 8 e superior

Agora você pode simplesmente fazer Instant.parse("2015-04-28T14:23:38.521Z") e obtenha a coisa correta agora, especialmente porque você deveria estar usando Instant em vez do quebrado java.util.Date com as versões mais recentes do Java.

Você deveria estar usando DateTimeFormatter ao invés de SimpleDateFormatter também.

Resposta original:

A explicação abaixo ainda é válida como o que o formato representa. Mas foi escrito antes do Java 8 ser onipresente, por isso usa as classes antigas que você não deve usar se estiver usando o Java 8 ou superior.

Isso funciona com a entrada com o seguinte Z Como demonstrado:

No padrão o T está escape com ' Em ambos os lados.

O padrão para o Z No final está realmente XXX conforme documentado no Javadoc para SimpleDateFormat, simplesmente não está muito claro sobre como usá -lo desde Z é o marcador para o velho TimeZone informação também.

Q2597083.Java

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class Q2597083
{
    /**
     * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone.
     */
    public static final TimeZone UTC;

    /**
     * @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a>
     */
    public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

    /**
     * 0001-01-01T00:00:00.000Z
     */
    public static final Date BEGINNING_OF_TIME;

    /**
     * 292278994-08-17T07:12:55.807Z
     */
    public static final Date END_OF_TIME;

    static
    {
        UTC = TimeZone.getTimeZone("UTC");
        TimeZone.setDefault(UTC);
        final Calendar c = new GregorianCalendar(UTC);
        c.set(1, 0, 1, 0, 0, 0);
        c.set(Calendar.MILLISECOND, 0);
        BEGINNING_OF_TIME = c.getTime();
        c.setTime(new Date(Long.MAX_VALUE));
        END_OF_TIME = c.getTime();
    }

    public static void main(String[] args) throws Exception
    {

        final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);
        sdf.setTimeZone(UTC);
        System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));
        System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));
        System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));
        System.out.println("sdf.parse(\"2015-04-28T14:23:38.521Z\") = " + sdf.parse("2015-04-28T14:23:38.521Z"));
        System.out.println("sdf.parse(\"0001-01-01T00:00:00.000Z\") = " + sdf.parse("0001-01-01T00:00:00.000Z"));
        System.out.println("sdf.parse(\"292278994-08-17T07:12:55.807Z\") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));
    }
}

Produz a seguinte saída:

sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z
sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z
sdf.format(new Date()) = 2015-04-28T14:38:25.956Z
sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015
sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1
sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994

Outras dicas

tl; dr

Instant.parse( "2010-10-02T12:23:23Z" )

ISO 8601

Esse formato é definido pelo ISO 8601 Padrão para formatos de string de data de data.

Ambos:

… Use formatos ISO 8601 por padrão para analisar e gerar strings.

Você deve geralmente Evite usar o antigo java.util.date/.Calendar & java.text.simpledateFormat Classes, pois são notoriamente problemáticas, confusas e falhas. Se necessário para interoperar, você pode se converter de um lado para o outro.

Java.Time

Construído em Java 8 e posterior é o novo Java.Time estrutura. Inspirado por Joda-Time, definido por JSR 310, e estendido pelo Threeten-Extra projeto.

Instant instant = Instant.parse( "2010-10-02T12:23:23Z" );  // `Instant` is always in UTC.

Converter para a classe antiga.

java.util.Date date = java.util.Date.from( instant );  // Pass an `Instant` to the `from` method.

Fuso horário

Se necessário, você pode atribuir um fuso horário.

ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );  // Assign a time zone adjustment from UTC.

Converter.

java.util.Date date = java.util.Date.from( zdt.toInstant() );  // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.

Joda-Time

ATUALIZAÇÃO: O projeto Joda-Time está agora no modo de manutenção. A equipe aconselha a migração para o Java.Time Aulas.

Aqui está algum código de exemplo no Joda-Time 2.8.

org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC );  // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.

Converter para a classe antiga. Observe que o fuso horário atribuído é perdido na conversão, pois o Judate não pode ser atribuído um fuso horário.

java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class.

Fuso horário

Se necessário, você pode atribuir um fuso horário.

DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone );

Sobre Java.Time

o Java.Time A estrutura é incorporada ao Java 8 e mais tarde. Essas aulas suplantam o velho problemático legado classes de data de data, como java.util.Date, Calendar, & SimpleDateFormat.

o Joda-Time Projeto, agora em Modo de manutenção, aconselha a migração para o Java.Time Aulas.

Para saber mais, consulte o Oracle Tutorial. E Pesquise o excesso de pilha para muitos exemplos e explicações. Especificação é JSR 310.

Você pode trocar Java.Time objetos diretamente com seu banco de dados. Use um Driver JDBC em conformidade com JDBC 4.2 ou mais tarde. Não há necessidade de cordas, sem necessidade de java.sql.* Aulas.

Onde obter as aulas de Java.Time?

  • Java SE 8, Java SE 9, e depois
    • Construídas em.
    • Parte da API Java padrão com uma implementação agrupada.
    • O Java 9 adiciona alguns recursos e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade Java.Time está em volta para Java 6 e 7 em Threeten-Backport.
  • Android
    • Versões posteriores das implementações do pacote Android das classes Java.Time.
    • Para Android anterior (<26), o Threetenabp Adaptação do projeto Threeten-Backport (Mencionado acima). Ver Como usar o threetenabp….

o Threeten-Extra O projeto estende Java.Time com classes adicionais. Este projeto é um terreno de prova para possíveis adições futuras ao Java.Time. Você pode encontrar algumas aulas úteis aqui, como Interval, YearWeek, YearQuarter, e mais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top