[ Foro de Java ]

Ejercicio de manejo de fechas

18-Feb-2015 13:22
Invitado ()
15 Respuestas

Añada a la clase StringUtils un método public y static llamado dates que devuelva un resultado de tipo String. El método tendrá 1 parámetro que será un objeto  de la clase String.

El método devolverá un objeto de la clase String que estará formado por la concatenación, en orden de aparición y separadas por un espacio, de todas las fechas contenidas en la ristra pasada cómo parámetro. No habrá espacios al principio ni al final de la ristra resultante.

Las fechas a recolectar estarán formadas por diez caracteres (formato "dd/mm/aaaa") y se tendrán en cuenta las siguientes consideraciones:

Todas las fechas que aparezcan estarán correctamente formadas.
El caracter '/' no aparecerá nunca cumpliendo otra función que no sea formar parte de una fecha.
La ristra pasada como parámetro podría no contener ninguna fecha.


18-Feb-2015 15:20
Nacho Cabanes (+30)

¿Y la duda es...?

(No esperes que alguien haga todo tu ejercicio por ti):
http://www.aprendeaprogramar.com/preguntasFrecuentes.php#incorrecciones


21-Feb-2015 02:53
Invitado ()

yo en ese ejercicio tengo un problema y es que no se como localizar la segunda barra de la fecha, solo se cuando solo aparecen una fecha y no mas de una. ayuda por favor


21-Feb-2015 13:27
Invitado ()


 
public class StringUtils {
    public static String dates (String s1){
 
	String contador = "";
 
        for(int i = 0; i < s1.length(); i++){
 
	if (s1.charAt(i) == '/'){
		contador = s1.substring(s1.indexOf(s1.charAt(i))-2,s1.indexOf(s1.charAt(i))+8);
		}
            }
	}
        return contador;
 
    }
}    
 
 


El problema que tengo es que no se que código tengo que poner para que me lea aparte mas de una fecha


21-Feb-2015 14:51
Nacho Cabanes (+30)

No acabo de entender lo que te piden... Yo diría que recibes una cadena que es una serie de fechas separadas por espacios y devuelves las fechas, separadas por un único espacio y sin espacios iniciales ni finales.

Si fuera así, y las fechas están bien formadas desde un principio, no tendrías más que eliminar los espacios redundantes. Los espacios iniciales y finales los puedes eliminar con cadena.trim() y puedes reemplazar cada par de espacios por un único espacio con cadena.replace().

De hecho, si realmente necesitaras saber dónde están las barras,  y las fechas está bien formadas, sería trivial: una está en la tercera posición y otra en la sexta.

La única complicación es si las fechas que te pasan como parámetro no están bien formadas, pero te dicen que "Todas las fechas que aparezcan estarán correctamente formadas". Lo que no queda claro es si eso se refiere a la salida o también a tus datos de entrada.


21-Feb-2015 15:12
Mario Gonzalez Garcia

Exacto, una estaría en la tercera y otra en la sexta, pero el problema que tengo es que cuando es mas de una fecha no se que hacer para que el programa me añada mas de una fecha, con el código que tengo solo me añade la primera fecha que aparece pero no si son más de una y no se que código poner para esto. Solo se refiere a la salida, te dan unos ciertas fechas juntos con letras y sin espacios y lo que tienes que hacer es separar la fechas encontradas y separarlas por un espacio sin son mas de una. Si me haces el favor de decirme como lo pondrías tu me harías un favor.


21-Feb-2015 16:06
Nacho Cabanes (+30)

Pon un ejemplo de como son esos datos de entrada, para que vea los problemas que te puedes encontrar


21-Feb-2015 16:10
Mario Gonzalez Garcia

Por ejemplo:
probando: dates("10/09/2008abcdefghi12/12/2012jklmnñop14/02/2001qrstuvwxyz08/07/1999").
Se obtiene "10/09/2008", y debería obtenerse  "10/09/2008 12/12/2012 14/02/2001 08/07/1999"


21-Feb-2015 16:26
Nacho Cabanes (+30)

Ah vale, entendido.

Yo haría lo siguiente, que funcionará tanto si hay caracteres alfabéticos como si hay espacios iniciales, finales o intermedios y también si hay otros símbolos de puntuación:

- Dentro del "for" que revisa tu cadena, yo guardaría el carácter en la cadena de destino cuando se encuentre entre 0 y 9 o sea una barra inclinada.

- Si es cualquier otro carácter, guardas un espacio.

- Al final, eliminas los espacios redundantes reemplazando cada para de espacios por uno solo, con

 
while (texto.contains(" "))
    texto = texto.replace("  ", " ");
 


- Finalmente, eliminas los espacios iniciales con "trim".


21-Feb-2015 16:38
Mario Gonzalez Garcia

No lo entiendo muy bien, así?
public class StringUtils {
   public static String dates (String s1){
       
       
       String s2 = s1.trim();
       String contador = "";
       
       for(int i = 0; i < s2.length("/"); i++){
       
       while (s2.contains(" "))
           s2 = s2.replace("  ", " ");
       
           if (s2.charAt(i) == '/'){
               contador = s2.substring(s2.indexOf(s2.charAt(i))-2,s2.indexOf(s2.charAt(i))+8);
               
           }
           
           
       }
       
         
       return contador;
   
   }
}    


21-Feb-2015 16:41
Nacho Cabanes (+30)

No, el "while" iría tras el "for", de modo que actuaría sobre la variable "contador", antes de devolverla, no en cada pasada en la que analizas letra a letra.

En el "for" no sería necesario ningún "substring", sino un

si el caracter es "/" o es mayor-o-igual que "0" y menor-o-igual-que "9"
   s2 = s2 + caracter
en caso contrario
   s2 = s2 + " "


21-Feb-2015 17:01
Mario Gonzalez Garcia

Ahora mira  a ver si lo tendría mejor, cree un if con esas condiciones debajo del while y modifique el for:

public class StringUtils {
   public static String dates (String s1){
       
       
       String s2 = s1.trim();
       String contador = "";
       
       for(int i = 0; i < s2.length(); i++){
       
       while (s2.contains(" "))
           s2 = s2.replace("  ", " ");
       
           if (i == '/' || i >= 0 && i <= 9){
               s2 = s2 + i;
           }else{
               s2 = s2 + " ";
           }
       
   }
       
       return contador;
   
   }
}    


21-Feb-2015 17:15
Mario Gonzalez Garcia

si me pasaras el ejercicio entero como lo harías tu mucho mejor, que llevo con esto ya desde antes de ayer


21-Feb-2015 18:15
Invitado (anonimo)

Este ejercicio se cierra esta noche, si pudiera hacerlo lo antes posible se lo agradecería. Yo tampoco entiendo lo que pusistes anteriormente, si pudieras pasarlo mejor


21-Feb-2015 23:47
Invitado (Anonimo)


 
public class StringUtils {
¡
    public static String dates (String s1){
 
        String result = "";
        if (s1.indexOf('/') == -1){
            return result;
        }
        for(int i = 0; i < s1.length(); i++){
            if (s1.charAt(i) == '/' || s1.charAt(i) >= '0' && s1.charAt(i) <= '9'){
                result = result + s1.charAt(i);
            } else {
                result = result + " ";
            }
        }
        if (result.length() <= 20){
            return result.substring(result.indexOf('/')-2,result.indexOf('/')+8);
        }
        return result.replaceAll(" +", " ").trim();
    }
 


Sería así, los dos últimos errores no se como se resolverían:
Error1 -> Se obtiene "12/10/201325/09/1999", y debería obtenerse  "12/10/2013 25/09/1999"
Error2 -> Se obtiene "12/12/2012 08071999", y debería obtenerse  "12/12/2012"

Alguna ayuda?


22-Feb-2015 00:27
Nacho Cabanes (+30)

El segundo caso, de cifras numéricas que no son fecha, no estaba entre los casos de prueba que comentabas. En el primer caso, no sé cual es el dato de entrada que te daban, si son dos fechas sin espacio intermedio o si es que tu programa está borrando espacios de más. Ten en cuenta que si los ejemplos que has dicho de los datos de entrada son poco detallados, puedes encontrarte con una solución demasiado simplista, que no se comporte bien en todos los casos, y puede ser más trabajoso "parchear" esa solución sobresimplificada que elaborar una solución más general desde un principio.

Pero vamos a los problemas (que quizá se hubieran evitado antes conociendo esos casos de prueba): Si también te pueden pasar secuencias de números que no sean parte de fechas (pero a la vez, que no estén pegadas a una fecha), una forma simple de resolverlo  sería no devolver directamente ese resultado del "trim", sino, una vez que tienes una serie de subcadenas separadas por espacios, hacer un "split" para convertirlo en un array de subcadenas y así poder ver de forma sencilla cuales de esas subcadenas es válida (barra en las posiciones tercera y sexta) y cuáles no lo son.

Si además te pueden dar varias series de fechas sin separación entre ellas, esa misma idea te serviría ampliándola apenas un poco, porque tendrías subcadenas cuya longitud no sería 10, sino 20 o cualquier otro múltiplo de 10, y en ese caso deberías partirlas.

Pero ese algoritmo no irá bien si además puedes tener entradas como
"123412/12/2010123412/12/20101234" en las que hay números pegados a fechas, y en ese caso no habría más remedio que trabajar recorriendo la cadena letra a letra (lo que, como te comentaba, puede llegar a ser más simple que tanto parche sobre una solución original que no preveía esos problemas).






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)