sábado, 10 de enero de 2009

Devuelve la fecha de hoy

Obtener la fecha de hoy en formato DD/MM/YYYY


JAVA

  public String hoy(){
      Date dFecha_actual = new Date();
      String sDia = Integer.toString(dFecha_actual.getDate());
      String sMes = Integer.toString(dFecha_actual.getMonth() + 1);
      String sAnio = Integer.toString(dFecha_actual.getYear() + 1900);
      if(sDia.length() == 1) sDia = "0" + sDia;
      if(sMes.length() == 1) sMes = "0" + sMes;
      String sFecha = sDia + "/" + sMes + "/" + sAnio;
      return sFecha;
  }

mes a literal

Convierte un mes a literal es decir en palabras 1 -->ENERO


JAVA
  public String mes2literal(int m){
    String sMes="";
    switch (m){
      case 1:
      sMes="ENERO";
      break;
      case 2:
      sMes="FEBRERO";
      break;
      case 3:
      sMes="MARZO";
      break;
      case 4:
      sMes="ABRIL";
      break;
      case 5:
      sMes="MAYO";
      break;
      case 6:
      sMes="JUNIO";
      break;
      case 7:
      sMes="JULIO";
      break;
      case 8:
      sMes="AGOSTO";
      break;
      case 9:
      sMes="SEPTIEMBRE";
      break;
      case 10:
      sMes="OCTUBRE";
      break;
      case 11:
      sMes="NOVIEMBRE";
      break;
      case 12:
      sMes="DICIEMBRE";
      break;
    }
    return sMes;
  }

numero a literal

Muchas veces se necesita presentar un numero en forma literal es decir en palabras, a continuacion se presenta una funcion que realiza la conversion de un numero entero a palabras 1000 --> "un mil"

POSTGRES SQL
create or replace function numero2literal(_num text) returns text as $$
------------------------
-- Autor: Luis Jordan P.
------------------------

declare
  _literal text;
  _numero text;
begin
  
  _numero:=ltrim(_num,'0');
  _numero:=replace(_numero,',','');
  if length(_numero)=1 then
    SELECT CASE
      WHEN _numero=0 THEN 'cero'
      WHEN _numero=1 THEN 'un'
      WHEN _numero=2 THEN 'dos'
      WHEN _numero=3 THEN 'tres'
      WHEN _numero=4 THEN 'cuatro'
      WHEN _numero=5 THEN 'cinco'
      WHEN _numero=6 THEN 'seis'
      WHEN _numero=7 THEN 'siete'
      WHEN _numero=8 THEN 'ocho'
      WHEN _numero=9 THEN 'nueve'
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero)=2 then
    SELECT CASE
      WHEN substring(_numero,1,1)=1 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'diez'
        WHEN substring(_numero,2,1)=1 THEN 'once'
        WHEN substring(_numero,2,1)=2 THEN 'doce'
        WHEN substring(_numero,2,1)=3 THEN 'trece'
        WHEN substring(_numero,2,1)=4 THEN 'catorce'
        WHEN substring(_numero,2,1)=5 THEN 'quince'
        WHEN substring(_numero,2,1) between 6 and 9 THEN 'diez y ' || numero2literal(substring(_numero,2,1))
      END  
      WHEN substring(_numero,1,1)=2 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'veinte'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'veinte y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=3 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'treinta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'treinta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=4 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'cuarenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'cuarenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=5 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'cincuenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'cincuenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=6 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'sesenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'sesenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=7 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'setenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'setenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=8 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'ochenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'ochenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=9 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'noventa'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'noventa y ' || numero2literal(substring(_numero,2,1))
      END
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero)=3 then
    SELECT CASE
      WHEN substring(_numero,1,1)=1 THEN CASE
        WHEN substring(_numero,2,2)='00' THEN 'cien'
        WHEN substring(_numero,2,2)<>'00' THEN 'ciento ' || numero2literal(substring(_numero,2,2))
      END  
      WHEN substring(_numero,1,1) between 2 and 8  THEN CASE
        WHEN substring(_numero,2,2)='00' THEN  numero2literal(substring(_numero,1,1)) || 'cientos'
        WHEN substring(_numero,2,2)<>'00' THEN numero2literal(substring(_numero,1,1)) || 'cientos ' || numero2literal(substring(_numero,2,2))
      END
      WHEN substring(_numero,1,1) = 9  THEN CASE
        WHEN substring(_numero,2,2)='00' THEN  'novecientos'
        WHEN substring(_numero,2,2)<>'00' THEN 'novecientos ' || numero2literal(substring(_numero,2,2))
      END
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero) between 4 and 6 then
    SELECT numero2literal(substring(_numero,1,length(_numero)-3)) || ' mil' ||
    CASE WHEN substring(_numero, length(_numero)-2,3)='000' THEN ''
    ELSE ' ' || numero2literal(substring(_numero, length(_numero)-2,3))
    END
    INTO _literal;
  end if;
  if length(_numero) between 7 and 12 then  
    SELECT numero2literal(substring(_numero,1,length(_numero)-6)) ||
    CASE WHEN substring(_numero,1,length(_numero)-6) ='1' THEN ' millon'
    ELSE ' millones'
    END
    ||
    CASE WHEN substring(_numero, length(_numero)-5,6)='000000' THEN ''
    ELSE ' ' || numero2literal(substring(_numero, length(_numero)-5,6))
    END
    INTO _literal;
  end if;

  return _literal;
end;
$$ language plpgsql;


select numero2literal('999999999999');

Resultado:
"novecientos noventa y nueve mil novecientos noventa y nueve millones novecientos noventa y nueve mil novecientos noventa y nueve"

fecha a literal (texto)

Muchas veces se necesita presentar una fecha en forma literal es decir en palabras, a veces con o sin el dia, a continuacion se presenta una funcion que realiza la conversion de una fecha YYYY-MM-DD a palabras nombre_dia dia de mes de año





POSTGRES SQL

CREATE OR REPLACE FUNCTION _fecha_literal(_fecha date, _dia integer) RETURNS text AS $$
-- _dia =0/1   sin/con el dia de la semana
------------------------
-- Autor: Luis Jordan P.
------------------------

declare
  _salida text;
begin
SELECT
  CASE WHEN _dia=1 THEN
    CASE WHEN rtrim(to_char(_fecha, 'day'))='sunday' THEN 'domingo '
           WHEN rtrim(to_char(_fecha, 'day'))='monday' THEN 'lunes '
           WHEN rtrim(to_char(_fecha, 'day'))='tuesday' THEN 'martes '
           WHEN rtrim(to_char(_fecha, 'day'))='wednesday' THEN 'miercoles '
           WHEN rtrim(to_char(_fecha, 'day'))='thursday' THEN 'jueves '
           WHEN rtrim(to_char(_fecha, 'day'))='friday' THEN 'viernes '
           WHEN rtrim(to_char(_fecha, 'day'))='saturday' THEN 'sabado '
      ELSE ''
      END
  ELSE ''
  END
  ||
  extract(day from _fecha) || ' de ' ||
    CASE WHEN extract(month from _fecha) =01 THEN 'enero'
         WHEN extract(month from _fecha) =02 THEN 'febrero'
         WHEN extract(month from _fecha) =03 THEN 'marzo'
         WHEN extract(month from _fecha) =04 THEN 'abril'
         WHEN extract(month from _fecha) =05 THEN 'mayo'
         WHEN extract(month from _fecha) =06 THEN 'junio'
         WHEN extract(month from _fecha) =07 THEN 'julio'
         WHEN extract(month from _fecha) =08 THEN 'agosto'
         WHEN extract(month from _fecha) =09 THEN 'septiembre'
         WHEN extract(month from _fecha) =10 THEN 'octubre'
         WHEN extract(month from _fecha) =11 THEN 'noviembre'
         WHEN extract(month from _fecha) =12 THEN 'diciembre'
     END
      || ' de ' || extract(year from _fecha)  
        
  INTO _salida;
  return _salida;
end; $$ LANGUAGE plpgsql;

SELECT _fecha_literal('2007-12-10'::date, 1);

Resultado:
lunes 10 de diciembre de 2007

Listar las hojas de un arbol a partir de un nodo


Si tengo una tabla arbol y deseo listar solo los nodos hojas a partir de un nodo raiz, puedo utilizar la funcion que presento a continuacion, si se selecciona un nodo hoja, se mostrara a si mismo, pero no se mostraran nodos padres

POSTGRES SQL

CREATE OR REPLACE FUNCTION listar_hijos(_tabla text, _id_campo text
, _id_padre text, _id integer, _where text) RETURNS text AS $$
------------------------
-- Autor: Luis Jordan P.
------------------------
declare
  _sql text;
  _bucle record;
  _i integer;
  _ids text;
begin
  _sql := '
  SELECT a.' || _id_campo || ' as id  FROM '|| _tabla ||' a, '|| _tabla ||' b
  WHERE a.'|| _id_padre ||' = b.'|| _id_campo ||'
  AND b.' || _id_campo || ' = ' || _id
  || _where;
  raise notice 'sql:%',_sql;
  _i:=0;
  _ids := '';
  for _bucle in
    execute _sql
  loop
    _i:=_i+1;
    if (_id <> _bucle.id) then
      _ids := _ids || (SELECT * FROM listar_hijos(_tabla, _id_campo
      , _id_padre, _bucle.id, _where));
    end if;
  end loop;
  if (_i = 0) then  -- comentar el if si se desea que se incluyan los padres
    _ids := _ids || ',' || _id;
  end if;
  return _ids;
end;
$$ LANGUAGE 'plpgsql' VOLATILE;

--ejemplo con WHERE:
--SELECT listar_hijos('tabla', 'id_campo', 'id_campo_padre', 1, ' AND a.campo=''Luis'' ');


SELECT listar_hijos('tabla', 'id_campo', 'id_campo_padre', 1, ' ');
Resultado:
,4,8,9,6,7

Listar los padres de una hoja en un arbol


En un tabla arbol, si tengo el identificador de una hoja(9) y quiero listar los padres de esta(5,2,1) hasta llegar a la raiz del arbol, puedo utilizar la funcion que muestro a continuacion, esta funcion es util para realizar consolidaciones(sumas de datos de hojas a los padres).

si tenemos la siguiente tabla:

POSTGRES SQL
create table tabla(
 id_campo serial primary key,
 id_campo_padre integer references tabla (id_campo),
 hoja boolean default true,
 codigo_campo text,
 campo text,
 nivel integer
);


create or replace function reporte_padres(_tabla text, _id_campo text
, _id_padre text, _codigo text, _campo text, _id integer)
returns setof record as $$
----------------------------
-- Autor: Luis A. Jordan P.
----------------------------
declare
 _sql text;
 _bucle record;
 _bucle1 record;
 _bucle2 record;
begin
 _sql := '
 SELECT ' || _id_campo || '::integer as id_campo
 , ' || _id_padre || '::integer as id_padre, ' ||
 _codigo || '::text as codigo, ' || _campo || '::text as campo
 , nivel::integer FROM ' || _tabla || ' WHERE ' || _id_campo || ' = ' || _id ;
 if _sql is null then
  raise exception 'Se coloco un nulo al formar el arbol de padres:
   SELECT %::integer as id_campo, %::integer as id_padre, %::text as codigo
   , %::text as campo, nivel::integer FROM % WHERE % = %
  ',_id_campo,_id_padre,_codigo,_campo,_tabla,_id_campo,_id;
 end if;
 for _bucle in
  execute _sql
 loop
  if(_bucle.id_padre<>_bucle.id_campo) then
   for _bucle1 in
    SELECT * FROM reporte_padres(_tabla, _id_campo
    , _id_padre, _codigo, _campo, _bucle.id_padre)
    as (id_campo integer, id_padre integer, codigo text
    , campo text, nivel integer) ORDER BY codigo
   loop 
    return next _bucle1;
   end loop;
  end if;
  return next _bucle;
 end loop;
 return ;
end;
$$ language plpgsql;



SELECT * FROM reporte_padres('tabla','id_campo', 'id_campo_padre'
, 'codigo', 'campo', 10)
AS (id_campo integer, id_padre integer, codigo text, campo text, nivel integer);

jueves, 22 de noviembre de 2007

Separar Miles

Aqui van funciones para separar miles, una en javascript, java y postgres sql , siguen distintos algoritmos para llegar al mismo resultado. Aun falta definir cual es la mas optima.




JAVASCRIPT

function separar_miles(numero1) {
  var numero=""+numero1;
  var signo="";
  var entero="";
  var decimales="";
  if (numero == "" || numero == undefined) return "0.00";
  if (numero.charAt(0) == "-") //es negativo {
    numero = numero.substr(1);
    signo = "-";
  }
  if (numero.indexOf(".") >= 0) { //tiene decimales
    entero=numero.substr(0, numero.indexOf("."));
    decimales = "" + (Math.round(parseFloat(numero.substr(numero.indexOf(".")))*100)/100);
    decimales = decimales.substr(1);
    if (decimales.length == 2) decimales += "0";
  }
  else {
    entero = numero;
    decimales = ".00";
  }
  var i = entero.length;
  numero = "";
  while (1) {
    if (i - 3 >= 0)
      numero = entero.substr(i - 3, 3) + "," + numero;
    else
      numero = entero.substr(0, i) + "," + numero;
    i = i - 3;
    if (i <= 0) break;
  }
  numero= signo + numero.substr(0, numero.length-1)+decimales;
  return numero;
}



JAVA


public String separar_miles(String s, String Separador, String Decimal){
  //entrada s=1000.4 separador="," Decimal="."
  //Salida 1,000.40
  if(!s.equals(" ")){
    if (s.length() > 0){
      String sDecimal;
      String sEntero;
      if (s.indexOf('.') == -1) s += ".00"; else if((s.length() - s.indexOf('.')) == 2) s += "0";
      sDecimal = s.substring(s.indexOf('.'));
      sDecimal = Decimal + sDecimal.charAt(1) + sDecimal.charAt(2);
      sEntero = s.substring(0, s.indexOf('.'));
      s = "";
      if (sEntero.length() > 3) {
        s = sEntero.substring(0, sEntero.length() % 3);
        sEntero = sEntero.substring(sEntero.length() % 3);
        if (s.length() > 0) s += Separador;
        while (sEntero.length() > 3){
          s += sEntero.substring(0, 3) + Separador;
          sEntero = sEntero.substring(3);
        }
      }
      s+= sEntero + sDecimal;
    }
    else s = "0" + Decimal + "00";
  }
  if(s.indexOf('-')+1==s.indexOf(','))
    s="-" + s.substring(2, s.length());
  return s;
}



POSTGRES SQL


create or replace function separar_miles(_numero numeric) returns text as $$
-- numero: -123456.00 es decir numero::numeric(15,2)
declare
  _signo text;
  _decimal text;
  _entero text;
  _auxiliar text;
begin
  _signo := '';
  if _numero::numeric(15,2) < 0 then
    _signo := '-';
  end if;
  _entero := abs(_numero)::integer::text;
  _decimal := substring((abs(_numero)-abs(_numero)::integer)::numeric(15,2)::text,2);
  _auxiliar := '';
  raise notice '% % %', _signo, _entero, _decimal;
  if (length(_entero) > 3) then
    _auxiliar := _auxiliar || substring(_entero, 1, length(_entero) % 3);
    _entero := substring(_entero, (length(_entero) % 3 ) + 1 );
    if (length(_auxiliar) > 0) then
      _auxiliar := _auxiliar || ',';
    end if;
    raise notice '% % %', _signo, _entero, _decimal;
    while (length(_entero) > 3) loop
      _auxiliar := _auxiliar || substring(_entero,1,3) || ',';
      _entero := substring(_entero,4);
      raise notice '% % %', _signo, _entero, _decimal;
    end loop;
    _auxiliar := _auxiliar || _entero;
  else
    _auxiliar := _entero;
  end if;
  _signo := _signo || _auxiliar || _decimal;
 
  return _signo;
end;
$$ language plpgsql;

SELECT * FROM separar_miles(-1234567890.1);