Descrobrir formato da data

Bom dia a todos,

Queria fazer um método que permitisse incrementar dias ou meses ou anos em uma data. Para isso usei a seguinte estrutura:

[code]GregorianCalendar gc = new GregorianCalendar( Integer.parseInt( sdate.substring( 6, sdate.length() ).trim().replace( ’ ', ‘0’ ), Integer.parseInt( sdate.substring( 3, 5 ).trim().replace( ’ ', ‘0’ ) ) - 1, Integer.parseInt( sdate.substring( 0, 2 ).trim().replace( ’ ', ‘0’ ) ) );

if ( DAY.equals( stype ) ) {
gc.add( Calendar.DAY_OF_MONTH, iamount );
}
else if ( MONTH.equals( stype ) ) {
gc.add( Calendar.MONTH, iamount );
}
else if( YEAR.equals( stype ) ) {
gc.add( Calendar.YEAR, iamount );
}[/code]

Esse método recebe como parâmetros uma data (String… motivo do meu problema), um inteiro que representa o incremento (ou decremento) e uma outra que define se o processamento ocorrerá sobre o dia, mês ou ano.
O meu problema está no momento em que eu gero o GregorianCalendar, ali eu tive que fazer um substring para obter as partes da data, no entanto, não tem como eu garantir que a data estará sempre nesse formato (dd/MM/yyyy).
Queria saber se tem alguma forma de descobrir o formato que está sendo utilizado para formatar a data na máquina do cliente? Ou, seria melhor ainda, se tem como eu obter as partes da data (dia, mês e ano) de uma String independentemente do formato em que ela se encontre?

Desde já agradeço pela atenção

[]s

Cara, para formatar datas costumo utilizar a SimpleDateFormat:

SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date suaData = // colocar sua data
String dataFormatada = dateFormat.format(suaData);

Mais detalhes voce conseguira nma APi, tem muitos recursos lá!
ate mais

pq vc nao usa o método add() da classe Calendar?

Calendar c = Calendar.getInstance();
//Adicionar um dia...
c.add(Calendar.DAY_OF_MONTH, 1)

Sem chance! Você só consegue quando o dia do mês for maior que 12. Imagine a data 12/12/2008. Impossível saber qual é o dia pra poder pegar o próximo.

[quote=Vini Fernandes] Cara, para formatar datas costumo utilizar a SimpleDateFormat:

SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date suaData = // colocar sua data
String dataFormatada = dateFormat.format(suaData);

Mais detalhes voce conseguira nma APi, tem muitos recursos lá!
ate mais

[/quote]

Olá Vini Fernandes,

O meu problema está no fato de não saber em que formato a data virá… pode ser uma string qualquer, inclusive inválida, eu queria identificar as partes adicionar dias, meses, anos, conforme a necessidade e retornar no mesmo formato que me foi enviada.

[]s

[quote=rissato]pq vc nao usa o método add() da classe Calendar?

Calendar c = Calendar.getInstance(); //Adicionar um dia... c.add(Calendar.DAY_OF_MONTH, 1) [/quote]

Ola rissato,

Eu pretendo usar sim o método add, só que não sei como informar a data para ele… eu estou utilzando o GregorianCalendar e não encontrei um construtor onde pudesse informar uma string contendo uma data qualquer… Eu preciso receber essa data e manipulá-la, da forma como mencionou, porém não sei como passar a data para ele…

alguma idéia?

[]s

[quote=g4j][quote=eberson_oliveira]
Queria saber se tem alguma forma de descobrir o formato que está sendo utilizado para formatar a data na máquina do cliente? Ou, seria melhor ainda, se tem como eu obter as partes da data (dia, mês e ano) de uma String independentemente do formato em que ela se encontre?
[/quote]

Sem chance! Você só consegue quando o dia do mês for maior que 12. Imagine a data 12/12/2008. Impossível saber qual é o dia pra poder pegar o próximo.[/quote]

Olá g4j,

Por isso mesmo eu queria descobrir uma forma de descobrir uma forma de identificar o formato ou passá-lo a algum objeto que identifique automaticamente… Imaginei que tivesse alguma api que tivesse acesso a esse tipo de informação, mas não estou encontrando nada… Pensei em procurar, inicialmente, no Locale, mas não achei nada que eu pudesse e/ou soubesse usar…

Tem alguma solução/idéia?

[]s

GregorianCalendar não tem um construtor que recebe uma string. Em vez disso, normalmente se faz algo parecido com o seguinte:

Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
Date dt = df.parse ("12/12/2008");
cal.setTime (dt);

[quote=eberson_oliveira][quote=rissato]pq vc nao usa o método add() da classe Calendar?

Calendar c = Calendar.getInstance(); //Adicionar um dia... c.add(Calendar.DAY_OF_MONTH, 1) [/quote]

Ola rissato,

Eu pretendo usar sim o método add, só que não sei como informar a data para ele… eu estou utilzando o GregorianCalendar e não encontrei um construtor onde pudesse informar uma string contendo uma data qualquer… Eu preciso receber essa data e manipulá-la, da forma como mencionou, porém não sei como passar a data para ele…

alguma idéia?

[]s[/quote]

Calendar c = Calendar.getInstance();
//Setar a data com a data atual...
c.setTime(new Date());
//Adicionar um dia...
c.add(Calendar.DAY_OF_MONTH, 1)

[quote=thingol]GregorianCalendar não tem um construtor que recebe uma string. Em vez disso, normalmente se faz algo parecido com o seguinte:

Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
Date dt = df.parse ("12/12/2008");
cal.setTime (dt);
[/code][/quote]

Olá thingol,

Entendi o seu exemplo.... acho que não estou conseguindo me expressar...
Eu pretendo receber uma data num formato qualquer ("dd/MM/yyyy", "d/M/yy", etc ), adicionar um mês, por exemplo, e retorná-la no mesmo formato em que recebi (para não alterar o formato de quem invocou o meu método)
Já fiz vários testes, mas não obtive sucesso...

Entendeu o que estou tentando fazer? Não sei se é possível...

grato pela atenção,

[]s

[quote=rissato][quote=eberson_oliveira][quote=rissato]pq vc nao usa o método add() da classe Calendar?

Calendar c = Calendar.getInstance(); //Adicionar um dia... c.add(Calendar.DAY_OF_MONTH, 1) [/quote]

Ola rissato,

Eu pretendo usar sim o método add, só que não sei como informar a data para ele… eu estou utilzando o GregorianCalendar e não encontrei um construtor onde pudesse informar uma string contendo uma data qualquer… Eu preciso receber essa data e manipulá-la, da forma como mencionou, porém não sei como passar a data para ele…

alguma idéia?

[]s[/quote]

Calendar c = Calendar.getInstance(); //Setar a data com a data atual... c.setTime(new Date()); //Adicionar um dia... c.add(Calendar.DAY_OF_MONTH, 1) [/quote]

Olá rissato,

Isso funciona com a data atual… mas se for uma data qualquer, num formato qualquer e string ainda…
como faço para manipulá-la e retornar o resultado no mesmo formato que recebi?

[]s

Eu pretendo receber uma data num formato qualquer ("dd/MM/yyyy", "d/M/yy", etc ), adicionar um mês, por exemplo, e retorná-la no mesmo formato em que recebi (para não alterar o formato de quem invocou o meu método) 

Você pode então fazer o seguinte: digamos que existam 3 formatos que você aceite (afinal de contas, seu programa não usa inteligência artificial, ou usa?). Então crie 3 DateFormat, um para cada formato aceito.
Use setLenient(false) para que o método parse gere uma exceção se não estiver no formato aceito.
Se você conseguir ler o dado, então use o formato para formatar o resultado na volta.

[quote=thingol] Eu pretendo receber uma data num formato qualquer ("dd/MM/yyyy", "d/M/yy", etc ), adicionar um mês, por exemplo, e retorná-la no mesmo formato em que recebi (para não alterar o formato de quem invocou o meu método)

Você pode então fazer o seguinte: digamos que existam 3 formatos que você aceite (afinal de contas, seu programa não usa inteligência artificial, ou usa?). Então crie 3 DateFormat, um para cada formato aceito.
Use setLenient(false) para que o método parse gere uma exceção se não estiver no formato aceito.
Se você conseguir ler o dado, então use o formato para formatar o resultado na volta. [/quote]

Entendi… vou adotar a sua solução… farei alguns testes e depois coloco o resultado. Sobre a inteligência artificial, só não uso porque não sei… :cry: mas quando aprender… volto aqui e coloco a solução usando esse conceito :smiley:

Muito grato pela ajuda

[]s

[quote]

Olá rissato,

Isso funciona com a data atual… mas se for uma data qualquer, num formato qualquer e string ainda…
como faço para manipulá-la e retornar o resultado no mesmo formato que recebi?

[]s[/quote]

Só vc substituir o “new Date()” pela data que vc quer… e pra isso vc nao precisa nem pensar em formato…

Olá a todos,

Montei o código da seguinte maneira:

[code]String[] formatos = new String[] { “dd/MM/yyyy”, “dd/MM/yy” };

SimpleDateFormat df = null;
Date date = null;

for ( int i = 0; i < formatos.length; i++ ) {
df = new SimpleDateFormat( formatos[ i ] );
df.setLenient( false );

 try {
    date = df.parse( sdate );
    break;
 }
 catch ( ParseException e ) {}

}

if ( date == null || df == null ) {
throw new IllegalArgumentException( “Formato inválido!!!” );
}

GregorianCalendar gc = new GregorianCalendar();
gc.setTime( date );

if ( “DAY”.equals( stype ) ) {
gc.add( Calendar.DAY_OF_MONTH, iamount );
}
else if ( “MONTH”.equals( stype ) ) {
gc.add( Calendar.MONTH, iamount );
}
else if ( “YEAR”.equals( stype ) ) {
gc.add( Calendar.YEAR, iamount );
}

return df.format( gc.getTime() );[/code]

Coloquei apenas dois tipos (só para ver se funcionaria), e fiz o seguinte teste:

System.out.println( Teste.calculateDate( "01/12/2008", 1, "DAY" ) ); //deveria retornar 02/12/2008 System.out.println( Teste.calculateDate( "01/12/08" , 1, "DAY" ) ); //02/12/08 System.out.println( Teste.calculateDate( "28/02/2008", 1, "DAY" ) ); //29/02/2008 System.out.println( Teste.calculateDate( "01/03/08" , 1, "DAY" ) ); //01/04/08 System.out.println( Teste.calculateDate( "01/03/2004", 1, "MONTH" ) ); //01/04/2004 System.out.println( Teste.calculateDate( "01/05/2006", -1, "MONTH" ) ); //01/04/2006

obtive o seguinte resultado:

02/12/2008 02/12/0008 29/02/2008 02/03/0008 01/04/2004 01/04/2006

Como faço para que ele entender que deve retornar 02/12/08, por exemplo, ao invés de 02/12/0008?

Usei o setLenient( false )… mas quando tentou pegar uma data: “02/12/08” com formato “dd/MM/yyyy” não deu exception… alguma idéia?

Agradeço desde já,

[]s

Acho que você tem de testar primeiro o “dd/MM/yy” e depois o “dd/MM/yyyy”.

Uma opção crie uma expressão regular para validar se a data esta no formato requerido por exemplo:

Validar este formato: dd/MM/yyyy


Pattern patter =  Pattern.compile("(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{4}");
Matcher match = patter.matcher(periodo);

if (!match.matches())
 // o que fazer a data nao esta no formato requerido ...

Fica a seu critério …

Olá thingol,

Fiz o teste que vc sugeriu e funcionou… sabe dizer porque não lançou exception quando mandei a data no formato “errado”?

[quote=ramilani12]
Uma opção crie uma expressão regular para validar se a data esta no formato requerido por exemplo:

Validar este formato: dd/MM/yyyy

[code]
Pattern patter = Pattern.compile("(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{4}");
Matcher match = patter.matcher(periodo);

if (!match.matches())
// o que fazer a data nao esta no formato requerido … [/code][/quote]

Olá ramilani12,

Gostei do formato por expressão regular… no entanto, como faço para contemplar algo desse tipo: “MM/dd/yyyy” e “dd/MM/yyyy”?
tem alguma idéia?

[]s

Oras, é só inverter a expressão:

1º Exemplo: valida se o formato está dd/mm/yyyy


Pattern patter =  Pattern.compile("(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{4}");

2º Exemplo valida se está neste formato: mm/dd/yyyy


Pattern patter =  Pattern.compile("(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])/\d{4}");

(0[1-9]|[1-2][0-9]|3[0-1]) -> Aqui valida o dia com as seguintes ocorrências : 01 , 17 ou 31
(0[1-9]|1[0-2]) -> Aqui valida o mês com as seguintes ocorrências: 01 , 09 , 10 até 12
\d{4} -> Valida o ano 2009 , 2010 com tamanho limitado a 4, bom ira demorar um pouco até chegarmos no ano de 20001

[quote=ramilani12]Oras, é só inverter a expressão:

1º Exemplo: valida se o formato está dd/mm/yyyy


Pattern patter =  Pattern.compile("(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{4}");

2º Exemplo valida se está neste formato: mm/dd/yyyy


Pattern patter =  Pattern.compile("(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])/\d{4}");

(0[1-9]|[1-2][0-9]|3[0-1]) -> Aqui valida o dia com as seguintes ocorrências : 01 , 17 ou 31
(0[1-9]|1[0-2]) -> Aqui valida o mês com as seguintes ocorrências: 01 , 09 , 10 até 12
\d{4} -> Valida o ano 2009 , 2010 com tamanho limitado a 4, bom ira demorar um pouco até chegarmos no ano de 20001[/quote]

Entendi o que disse, mas como faço pra saber o formato da seguinte data: “12/12/2002”, é “dd/MM/yyyy” ou é “MM/dd/yyyy”?

Vou colocar a classe… assim fica mais fácil de entender o meu contexto:

[code]package testes;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TesteCalculaData {

private Map getFormatosPermitidos() {
Map mapa = new HashMap();

  mapa.put( Pattern.compile( "(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{4}" ), "dd/MM/yyyy" );
  mapa.put( Pattern.compile( "(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/\d{2}" ), "dd/MM/yy"   );
  
  return mapa;

}

public String calculateDate( String sdate, int iamount, String stype ) {

  SimpleDateFormat df = null;
  Date date = null;
  Map formatosPermitidos = getFormatosPermitidos();
  Iterator iterator = formatosPermitidos.keySet().iterator();
  Matcher match;
  
  while( iterator.hasNext() ){
     Pattern pattern = ( Pattern ) iterator.next();
     
     match = pattern.matcher( sdate );
     
     if ( match.matches() ){
        df = new SimpleDateFormat( ( String ) formatosPermitidos.get( pattern ) );
        df.setLenient( false );
        try {
           date = df.parse( sdate );
        }
        catch ( ParseException e ) {
           //tratar depois...
           e.printStackTrace();
        }

        break;
     }
     
  }

  if ( date == null || df == null ) {
     return "Deu erro na data: " + sdate;

// descomentar o codigo abaixo quando terminar a implementação
// throw new IllegalArgumentException( “Formato inválido!!!” );
}

  GregorianCalendar gc = new GregorianCalendar();
  gc.setTime( date );

  if ( "DAY".equals( stype ) ) {
     gc.add( Calendar.DAY_OF_MONTH, iamount );
  }
  else if ( "MONTH".equals( stype ) ) {
     gc.add( Calendar.MONTH, iamount );
  }
  else {
     gc.add( Calendar.YEAR, iamount );
  }
  
  String sformatDate =  df.format( gc.getTime() );

  return sformatDate;

}

public static void main( String[] args ) {

  TesteCalculaData calulaData = new TesteCalculaData();
  
  System.out.println( calulaData.calculateDate( "01/12/2008", 1, "DAY"   ) );
  System.out.println( calulaData.calculateDate( "01/12/08", 1, "DAY"   ) );
  System.out.println( calulaData.calculateDate( "28/02/2008", 1, "DAY"   ) );
  System.out.println( calulaData.calculateDate( "01/03/08", 1, "DAY"   ) );
  System.out.println( calulaData.calculateDate( "01/03/2004", 1, "MONTH" ) );
  System.out.println( calulaData.calculateDate( "01/05/2006", -1, "MONTH" ) );
  System.exit( 0 );

}

}
[/code]

Entende o que estou tentando explicar… não sei como fazer pra tratar essas situações…

[]s