Fechas, números y monedas con java

agosto 22, 2008

Si quieres trabajar con fechas y monedas de todo el mundo deberás familiarizarte con estas clases de java:

java.util.Date

Muchos de sus métodos ya están obsoletos, pero usamos esta clase para crear un enlace entre las clases Calendar y DateFormat. Una instancia de Date representa una fecha y hora mutable, con respecto a un mili segundo.

java.util.Calendar

Esta clase provee una gran cantidad de métodos que te ayudarán a manipular fechas y horas. Por ejemplo si quieres saber qué día de la semana es el 20 de Febrero del 2015, esta clase te lo resolverá.

java.text.DateFormat

Esta clase se usa para dar formato a fechas con varios estilos como por ejemplo “21/02/89” o “Febrero 21, 1989,” y también te dará la fecha en el formato de una cierta “localidad” del mundo.

java.text.NumberFormat

Esta clase se usa para formatear números y monedas con Locales de todo el mundo

java.util.Locale

Esta clase se usa en conjunto con DateFormat y NumberFormat para dar formato a los números, fechas y monedas de diferentes regiones del mundo. Si no quieres manejar las fechas con formato puedes usar la clase Locale directamente con la clase Calendar.

Cuando trabajas con fechas y números, usualmente usarás varias clases juntas, es muy importante comprender cómo es que las clases anteriores se relacionan entre sí. Por ejemplo deberás saber que para formatear una fecha de acuerdo a una localidad específica, necesitas crear primero el objeto Locale antes que el objeto DateFormat, porque necesitarás el objeto Locale como un argumento para DateFormat, como verémos más adelante.

En caso de querer… Pasos
Obtener fecha y hora 1. Crear una fecha: Date d = new Date();
2. Obtener su valor: Sting s = d.toString();
Obtener un objeto que te permita realizar cálculos de fecha y hora en tu Locale 1. Crear un Calendar: Calendar c = Calendar.getInstance();
2. Utiliza c.add(...); y c.roll(...); para realilzar manipulaciones en la fecha y hora
Obtener un objeto que te permita realizar cálculos de fecha y hora en un Locale diferente 1. Crear un Locale: Locale loc = new Locale(idioma); ó Locale loc = new Locale(idioma, país);
2. Crea un calendario con esa Locale Calendar c = Calendar.getInstance(loc);
3. Utiliza c.add(...); y c.roll(...); para realilzar manipulaciones en la fecha y hora
Obtener un objeto que te permita realizar cálculos de fecha y hora y luego darle formato para diferentes locales y diferentes estilos de fecha 1. Crear un Locale: Locale loc = new Locale(idioma); ó Locale loc = new Locale(idioma, país);
2. Crea un calendario con esa Locale Calendar c = Calendar.getInstance(loc);
3. Convierte el calendario a fecha:Date d = c.getTime();
4. Crea un DateFormat para cada Locale: DateFormat df = DateFormat.getDateInstance(estilo, loc)
5. Usa el método format para crear fechas formateadas: String s = df.format(d);

La clase Calendar

Esta clase nos permite manipular las fechas de manera sencilla. Para crear una instancia de Calendar debemos de hacer lo siguiente, ya que es una clase abstracta:

Calendar cal = Calendar.getInstance();

así “cal” será una referencia a una instancia de una subclase de Calendar. probablemente sea java.util.GregorianCalendar, pero eso no importa, ya que estaremos usando la API de Calendar.

import java.util.*;
class Fechas {
  public static void main(String[] args) {
    Date d = new Date();
    System.out.println("Fecha 1: " + d.toString());
    Calendar c = Calendar.getInstance();
    c.setTime(d);                          // #1
    if(c.SUNDAY == c.getFirstDayOfWeek())   // #2
    {
      System.out.println("el primer día de la semana es domingo");
    }
    System.out.println("Día de la semana "
                       + c.get(c.DAY_OF_WEEK));    // #3
    c.add(Calendar.MONTH, 1);                      // #4
    Date d2 = c.getTime();                         // #5
    System.out.println("Nueva fecha " + d2.toString() );
  }
}

Este código me produce:

Fecha 1: Wed Aug 20 13:13:13 CDT 2008
el primer día de la semana es domingo
Día de la semana 4
Nueva fecha Sat Sep 20 13:13:13 CDT 2008

En la línea 7 estamos asignando una fecha creada previamente al recién creado Calendar.
Luego en la línea 8 estamos preguntando si según el calendario usado el primer día de la semana es el domingo, si sí lo es, imprimirá “el primer día de la semana es domingo”.
En la línea 12 y 13 estamos imprimiendo el el número del dia de la semana, por medio del método get() de la clase Calendar, a este método le estamos pasando el campo de DAY_OF_WEEK de la clase Calendar.
En la línea 14 estamos agregando 1 mes a la fecha del Calendario, por medio del método add(), este método nos permite también modificar otros campos de la fecha.. algunos ejemplos:

c.add(Calendar.HOUR, -4);
c.add(Calendar.YEAR, 2);
c.add(Calendar.DAY_OF_WEEK, -2);

Y por último en la línea 15 estamos convirtiendo el valor del calendario a una instancia de Date.
Otro método muy importante que hay que conocer sobre la clase Calendar es el método roll(), este método hace lo mismo que add(), la diferencia es que con add(), si llegamos a aumentar 12 horas al calendario, y eran las 16:00 del 20 de agosto, la fecha se recorre a 04:00 del 21 de agosto, ahora si usamos el método roll(), la fecha quedaria solo como 04:00 del 20 de agosto.
Por ejemplo:

// asumamos que estamos a Octubre 8, 2001, y que c es una instancia de un calendario con esa fecha
c.roll(Calendar.MONTH, 9); // aumentamos 9 meses
Date d2 = c.getTime();
System.out.println(“nueva fecha ” + d2.toString() ; // observar el año en la salida!

Daría una salida similar a esta:
nueva fecha Fri Jul 08 19:46:40 MDT 2001
Observamos que el mes cambio de octubre a julio, pero el año es el mismo.

La clase DateFormat

Ya sabemos como crear y manipular fechas, ahora vamos a ver como darles formato:

import java.text.*;
import java.util.*;
class Fecha2 {
  public static void main(String[] args) {
    Date d1 = new Date(1000000000000L);//usamos el constructor basado en milisegundos, le pasamos un trillón de milisegundos

    DateFormat[] dfa = new DateFormat[6];
    dfa[0] = DateFormat.getInstance();
    dfa[1] = DateFormat.getDateInstance();
    dfa[2] = DateFormat.getDateInstance(DateFormat.SHORT);
    dfa[3] = DateFormat.getDateInstance(DateFormat.MEDIUM);
    dfa[4] = DateFormat.getDateInstance(DateFormat.LONG);
    dfa[5] = DateFormat.getDateInstance(DateFormat.FULL);
    for(DateFormat df : dfa) //recorremos el arreglo y mostramos la fecha con los distintos formatos
      System.out.println(df.format(d1));
  }
}

El codigo de arriba produce esto en mi JVM:

9/8/01 8:46 PM
Sep 8, 2001
9/8/01
Sep 8, 2001
September 8, 2001
Saturday, September 8, 2001

Examinando este codigo vemos unas cuantas cosas. Primero que nada, DateFormat es otra clase abstracta, así que no podemos usar new para crear instancias de DateFormat. En este caso usamos 2 métodos, getInstance() y getDateInstance(). También nos damos cuenta que getDateInstance() está sobrecargado, cuando veamos los Locales manejaremos otras versiones de getDateInstance().
Luego usamos campos estáticos de la clase DateFormat para personalizar nuestras instancias de DateFormat. Cada uno de estos campos estáticos representan un estilo de formato.
Podríamos deducir que la versión sin argumentos del método getDateInstance() nos da el mismo estilo que el método getDateInstance(DateFormat.MEDIUM) de la clase DateFormat, pero eso no siempre es así.
Otro método con el cual deberemos familiarizarnos es el método parse(), quién toma una String de fecha formateada con algun estilo de DateFormat y convierte la String en un objeto Date. Este método lanza una excepción(ParseException) en caso de que se le haya pasado un String mal formateado.
El siguiente código crea una instancia de Date, usa DateFormat.format() para pasar Date a String y luego usa parse() para regresar el String a Date:

import java.text.DateFormat;
import java.text.ParseException;
import java.util.*;

class Fechas3 {

 public static void main(String[] args) {
 Date d1 = new Date(1000000000000L);
 System.out.println("fecha 1= " + d1.toString());

 DateFormat df = DateFormat.getDateInstance(
 DateFormat.SHORT);
 String s = df.format(d1);
 System.out.println(s);
 try {
 Date d2 = df.parse(s);
 System.out.println("fecha parseada = " + d2.toString());
 } catch (ParseException pe) {
 System.out.println("erro de parseo");
 }
 }
}

El código de arriba produce en mi máquina:

fecha 1= Sat Sep 08 20:46:40 CDT 2001
9/8/01
fecha parseada = Sat Sep 08 00:00:00 CDT 2001

Hay que observar que perdimos precisión a la horade parsear la fecha, esto se debe a que la formateamos con el estilo DateFormat.SHORT.

La clase Locale

Esta clase es usada por DateFormat y NumberFormat para personalizar el formato de fechas y números con respecto a un Locale específico.

Esta clase tiene 2 constructores:

Locale(String lenguaje)
Locale(String lenguaje, String país)

El argumento de lenguaje representa un código ISO 639:

Código de lenguaje Descripción
de Alemán
en Inglés
fr Francés
ja Japonés
es Español
ko Coreano
zh Chino

una lista completa se puede encontrar aquí.

Por ejemplo si queremos manejar italiano en nuestra aplicación, sólo necesitamos el código del lenguaje, pero si queremos representar el italiano que se usa en suiza, necesitamos usar el segundo constructor pasándole el código de país de suiza “CH”

Locale locPT = new Locale("it");        // Italiano
Locale locBR = new Locale("it", "CH");  // Suiza

Esto nos daría una salida parecida a esto:

sabato 1 ottobre 2005
sabato, 1. ottobre 2005

Ahora hay que poner todo junto y hacer un código que crea un objeto de Calendar, le cambiamos la fecha a otro día cualquiera y luego lo mandamos a un objeto Date, para al final formatear esa fecha con diferentes Locales.

import java.text.DateFormat;
import java.util.*;

/**
 *
 * @author luis
 */
class Fechas4 {

 public static void main(String[] args) {
 Calendar c = Calendar.getInstance();
 c.set(1989, 1, 21); // Febrero 21, 1989
 // el  mes se basa en 0, osea Enero = 0
 // esa fecha es el día que nací

 Date d = c.getTime();
 Locale locIT = new Locale("it", "IT");  // Italy
 Locale locPT = new Locale("pt");        // Portugal
 Locale locBR = new Locale("pt", "BR");  // Brazil
 Locale locIN = new Locale("hi", "IN");  // India
 Locale locMEX = new Locale("es", "MX"); // México

 DateFormat dfUS = DateFormat.getInstance();
 System.out.println("US       " + dfUS.format(d));
 DateFormat dfUSfull = DateFormat.getDateInstance(
 DateFormat.FULL);
 System.out.println("US largo " + dfUSfull.format(d));

 DateFormat dfIT = DateFormat.getDateInstance(
 DateFormat.FULL, locIT);
 System.out.println("Italy    " + dfIT.format(d));
 DateFormat dfPT = DateFormat.getDateInstance(
 DateFormat.FULL, locPT);
 System.out.println("Portugal " + dfPT.format(d));
 DateFormat dfBR = DateFormat.getDateInstance(
 DateFormat.FULL, locBR);
 System.out.println("Brazil   " + dfBR.format(d));
 DateFormat dfIN = DateFormat.getDateInstance(
 DateFormat.FULL, locIN);
 System.out.println("India    " + dfIN.format(d));
 DateFormat dfMX = DateFormat.getDateInstance(
 DateFormat.FULL, locMEX);
 System.out.println("México   " + dfMX.format(d));
 }
}

En mi JVM me produce esta salida:

US       2/21/89 10:59 AM
US largo Tuesday, February 21, 1989
Italy    martedì 21 febbraio 1989
Portugal Terça-feira, 21 de Fevereiro de 1989
Brazil   Terça-feira, 21 de Fevereiro de 1989
India    ???????, ?? ??????, ????
México   martes 21 de febrero de 1989

Jeje pues no tengo soporte para los caracteres de India. Pero ya vimos como se puede dar formato a las fechas.

La clase NumberFormat

Al igual que la clase DateFormat, NumberFormat tambíen es Abstracta, entonces usaremos los métodos getInstance() o getCurrencyInstance(), para crear un objeto NumberFormat.

Ejemplo:

import java.text.NumberFormat;
import java.util.*;

/**
 *
 * @author luis
 */
class Numeros {

    public static void main(String[] args) {
        float f1 = 123.4567f;
        Locale locFR = new Locale("fr");    // Francia

        NumberFormat[] nfa = new NumberFormat[4];
        nfa[0] = NumberFormat.getInstance();
        nfa[1] = NumberFormat.getInstance(locFR);
        nfa[2] = NumberFormat.getCurrencyInstance();
        nfa[3] = NumberFormat.getCurrencyInstance(locFR);
        for (NumberFormat nf : nfa) {
            System.out.println(nf.format(f1));
        }
    }
}

Que me da esta salida:

123.457
123,457
$123.46
123,46 ¤

Como podemos ver estas clases son abstractas en su mayoría, aquí les pongo los constructores o métodos para crear instancias de estas clases.

Util.Date

new Date();
new Date(long milisegundosDesde010170);

util.Calendar

Calendar.getInstance();
Calendar.getInstance(Locale);

util.Locale

Locale.getDefault();
new Locale(String lenguaje);
new Locale(String lenguaje, String país);

text.DateFormat

DateFormat.getInstance();
DateFormat.getDateInstance();
DateFormat.getDateInstance(estilo);
DateFormat.getDateInstance(estilo, Locale);

Con esto ya pueden trabajar con fechas y números con diferentes formatos dependiendo del Locale que le especifiquen.

Una respuesta to “Fechas, números y monedas con java”

  1. Franjo Says:

    Que buen post !! java bien explicado y con codigo útil


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: