Analisar string até o momento com formato diferente em Java

91

Eu quero converter Stringa Dateem diferentes formatos.

Por exemplo,

Estou recebendo do usuário,

String fromDate = "19/05/2009"; // i.e. (dd/MM/yyyy) format

Eu quero converter isso fromDatecomo um objeto Date de "yyyy-MM-dd"formato

Como posso fazer isso?

Gnaniyar Zubair
fonte
2
Um objeto Date não tem formato, é apenas um número que representa a data. A data pode ser representada por uma String com o formato "aaaa-MM-dd".
user85421

Respostas:

181

Dê uma olhada em SimpleDateFormat. O código é mais ou menos assim:

SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

try {

    String reformattedStr = myFormat.format(fromUser.parse(inputString));
} catch (ParseException e) {
    e.printStackTrace();
}
Michael Myers
fonte
1
em vez de obter o formato de string, posso obter a saída no Dateformato?
Rachel de
4
@ Rachel: Claro, apenas use parsee não prossiga format. parseanalisa uma string para uma data.
Michael Myers
3
Mas parsedá-me date formatcomo, Fri Jan 06 00:01:00 EST 2012mas precisa no 2012-01-06formato de data
Rachel
1
@Rachel é porque quando você chama System.out.println(anyDateObject)o método toString () padrão é chamado, o que foi dito para imprimir nesse formato, por exemplo Fri Jan 06 00:01:00 EST 2012. Você precisa substituí-lo para atender às suas necessidades.
KNU
3
Para sua informação, as antigas classes problemáticas de data e hora como java.util.Date, java.util.Calendare java.text.SimpleDateFormatagora são legadas , suplantadas pelas classes java.time integradas ao Java 8 e Java 9. Veja o Tutorial da Oracle .
Basil Bourque
13

tl; dr

LocalDate.parse( 
    "19/05/2009" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

Detalhes

As outras respostas com java.util.Date, java.sql.Datee SimpleDateFormatagora estão ultrapassadas.

LocalDate

A maneira moderna de fazer data e hora é trabalhar com as classes java.time, especificamente LocalDate. A LocalDateclasse representa um valor apenas de data sem hora do dia e sem fuso horário.

DateTimeFormatter

Para analisar ou gerar uma String representando um valor de data e hora, use a DateTimeFormatterclasse.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "19/05/2009" , f );

Não confunda um objeto de data e hora com uma String representando seu valor. Um objeto de data e hora não tem formato , enquanto uma String tem. Um objeto de data e hora, como LocalDate, pode gerar uma String para representar seu valor interno, mas o objeto de data e hora e a String são objetos distintos separados.

Você pode especificar qualquer formato personalizado para gerar uma String. Ou deixe java.time fazer o trabalho de localização automática.

DateTimeFormatter f = 
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.CANADA_FRENCH ) ;
String output = ld.format( f );

Despeje para o console.

System.out.println( "ld: " + ld + " | output: " + output );

ld: 2009-05-19 | saída: mardi 19 mai 2009

Veja em ação em IdeOne.com .


Sobre java.time

A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e SimpleDateFormat.

O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .

Para saber mais, consulte o tutorial Oracle . E pesquise no Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de cordas, não há necessidade de java.sql.*classes.

Onde obter as classes java.time?

  • Java SE 8 , Java SE 9 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação agrupada.
    • Java 9 adiciona alguns recursos e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é portada para Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores de implementações de pacotes Android das classes java.time.
    • Para anteriormente Android (<26), o ThreeTenABP projeto adapta ThreeTen-Backport (mencionados acima). Consulte Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de provas para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .

Basil Bourque
fonte
12

Use a SimpleDateFormatclasse:

private Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat(format);
    return formatter.parse(date);
}

Uso:

Date date = parseDate("19/05/2009", "dd/MM/yyyy");

Para maior eficiência, você deseja armazenar seus formatadores em um hashmap. O hashmap é um membro estático de sua classe util.

private static Map<String, SimpleDateFormat> hashFormatters = new HashMap<String, SimpleDateFormat>();

public static Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = hashFormatters.get(format);

    if (formatter == null)
    {
        formatter = new SimpleDateFormat(format);
        hashFormatters.put(format, formatter);
    }

    return formatter.parse(date);
}
Agora
fonte
9
EMBARGO!! A ideia é boa, mas a implementação não. DateFormats não devem ser armazenados estaticamente, porque eles não são seguros para thread! Se eles forem usados ​​em mais de um thread (e isso é sempre arriscado com estática). FindBugs contém um detector para isso (com o qual contribuí inicialmente, depois de ser mordido. Veja dschneller.blogspot.com/2007/04/… :-))
Daniel Schneller
A entrada do seu blog é uma leitura interessante :-) E se o método parseDate em si for sincronizado? O problema, porém, é que provavelmente tornaria o código mais lento ...
Agora
1
Contanto que o método parseDate fosse o único método de acesso ao mapa, sincronizá-lo funcionaria. No entanto, isso - como você disse - introduziria um gargalo.
Daniel Schneller
8

Converta uma data de string para java.sql.Date

String fromDate = "19/05/2009";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date dtt = df.parse(fromDate);
java.sql.Date ds = new java.sql.Date(dtt.getTime());
System.out.println(ds);//Mon Jul 05 00:00:00 IST 2010
Ritesh Kaushik
fonte
3

Embora SimpleDateFormatrealmente funcione para as suas necessidades, você também pode querer verificar Joda Time , que aparentemente é a base para a biblioteca Date refeita em Java 7. Embora eu não a tenha usado muito, não ouvi nada além de coisas boas sobre isso e se você está manipulando datas extensivamente em seus projetos, provavelmente valeria a pena dar uma olhada.

James McMahon
fonte
1

Maneira simples de formatar uma data e convertê-la em string

    Date date= new Date();

    String dateStr=String.format("%td/%tm/%tY", date,date,date);

    System.out.println("Date with format of dd/mm/dd: "+dateStr);

saída: Data com formato dd / mm / dd: 21/10/2015

Khalid Habib
fonte
1

Um Dateobjeto não tem formato , é uma representação. A data pode ser apresentada por um Stringcom o formato de sua preferência .

Por exemplo, " yyyy-MM-dd", " yy-MMM-dd", " dd-MMM-yy" e etc.

Para conseguir isso, você pode usar o SimpleDateFormat

Tente isto,

        String inputString = "19/05/2009"; // i.e. (dd/MM/yyyy) format

        SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy"); 
        SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date dateFromUser = fromUser.parse(inputString); // Parse it to the exisitng date pattern and return Date type
            String dateMyFormat = myFormat.format(dateFromUser); // format it to the date pattern you prefer
            System.out.println(dateMyFormat); // outputs : 2009-05-19

        } catch (ParseException e) {
            e.printStackTrace();
        }

Isso resulta em: 19/05/2009

Dulith De Costa
fonte
1

Suponha que você tenha uma string como esta:

String mDate="2019-09-17T10:56:07.827088"

Agora queremos alterar esse Stringformato de data e hora separados em Java e Kotlin .

JAVA:

temos um método para a data de extração :

public String getDate() {
    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mDate);
        dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Return é este: 17/09/2019

E temos método para extrair o tempo :

public String getTime() {

    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mCreatedAt);
        dateFormat = new SimpleDateFormat("h:mm a", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Returné este: 10:56

KOTLIN:

temos uma função para a data de extração :

fun getDate(): String? {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val date = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
    return dateFormat.format(date!!)
}

Return é este: 17/09/2019

E temos método para extrair o tempo :

fun getTime(): String {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val time = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("h:mm a", Locale.US)
    return dateFormat.format(time!!)
}

Returné este: 10:56

Milad Salimi
fonte
Por favor, não ensine os mais jovens a usar a SimpleDateFormatclasse há muito desatualizada e notoriamente problemática . Pelo menos não como primeira opção. E não sem reservas. Hoje temos muito melhor em java.time, a moderna API Java de data e hora e seus DateTimeFormatter. Também SimpleDateFormatnão é possível analisar 6 decimais nos segundos (microssegundos) corretamente.
Ole VV
Quando executo seu segundo snippet, não entendo 10:56 AMcomo você diz que deveria, mas sim 11:09 AM(testado em Oracle jdk-11.0.3).
Ole VV
@ OleV.V. , Se um método estiver muito desatualizado, ele ficará obsoleto com uma linha como um sinal, se um método ou classe não estiver obsoleto, podemos usá-lo, não digo que seja a melhor maneira, talvez tenhamos uma maneira melhor, mas desta forma é simples e compreensível, se um método ou classe era antigo, não há razão para ser problemático e para o uso de DateTimeFormatternós precisamos minsdk 26ou mais do que isso não é bom
milad salimi
@ OleV.V. Mas obrigado pelo seu comentário e pelo seu segundo comentário, posso dizer que verifiquei várias vezes em duas aplicações e voltou10:56 AM
milad salimi
1
@ OleV.V. Ok, mas eu uso uma biblioteca quando não tenho como ou essa API (biblioteca) é muito melhor que o meu código, porque quando você adiciona uma biblioteca você adiciona alguns códigos ao seu projeto que podem não ser usados ​​e isso sobrecarrega o seu projeto, esta é a minha abordagem e sua abordagem é respeitável para mim.
milad salimi