Ir para conteúdo
Fórum Script Brasil
  • 0

Horas Por Extenso


Micheus

Pergunta

O objetivo da função HoraPorExtenso é a conversão de horas no formato TTime ou TDateTime para texto corrido (extenso).

1) Função auxiliar DecimalExtenso: ela está projetada para trabalhar com números entre 0 e 99, podendo ser ampliada para reaproveitamento em outras aplicações (extenso de valores).

O parâmetro Masculino foi introduzido para tratar questões de gênero (masc/fem), que ocorre quando fala-se em horas (fem), mas não em minutos (masc). Com o intúito de otimizar recursos, um type cast deste parâmetro para o tipo Byte é utilizado. Com isto, se este parâmetro for True teremos como resultado 1 ser for False, teremos zero. Ao multiplicarmos este "resultado" por 2 (cnUnidadeGenero[unidade +(Byte(Masculino)*2)]), estaremos indexando corretamente o vetor cnUnidadeGenero.

2) Função HoraPorExtenso: optou-se pelo parâmetro no formado TDateTime de modo a facilitar a processamento da função, bem como pela obrigação da validação do campo sendo passado no momento de sua chamada. Deste modo não há risco de excessões.

Como numa variável TDateTime/TTime (equivalente ao float) o valor das horas encontra-se na parte fracionária, multiplicando esta parte por 24 obtemos as horas. Com este processo, a "nova" parte fracionária corresponde aos minutos dentro daquela hora. Assim, multiplicando por 60, teremos o valor dos minutos.

const
  cnUnidadeGenero :array[1..4] of string   = ('uma', 'duas', 'um', 'dois');
  cnUnidade       :array[3..9] of string   = ('três', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove');
  cnDezena10      :array[11..19] of string = ('onze', 'doze', 'treze', 'quatorze', 'quinze', 'dezesseis', 
                                              'dezessete', 'dezoito', 'dezenove');
  cnDezena        :array[1..9] of string   = ('dez', 'vinte', 'trinta', 'quarenta', 'cinqüenta', 'sessenta', 
                                              'setanta', 'oitenta', 'noventa');

// monta apenas números decimais (até 99)
function DecimalExtenso(Num :integer; Masculino :Boolean) :string;
var
  Unidade,
  Dezena :integer;
begin
  if Num > 0 then
  begin
    Unidade := Num mod 10;
    Dezena := Num div 10;
    if Dezena = 0 then
    begin
      if Unidade <= 2 then  // Os números 1 e 2 podem variar em gênero
        Result := cnUnidadeGenero[Unidade +(Byte(Masculino)*2)]
      else
        Result := cnUnidade[Unidade]
    end else
      if Unidade = 0 then
        Result := cnDezena[Dezena]
      else
        if Dezena = 1 then
          Result := cnDezena10[Num]
        else
          if Dezena <= 9 then
            if Unidade <= 2 then  // Os números 1 e 2 podem variar em gênero
              Result := cnDezena[Dezena] + ' e ' +cnUnidadeGenero[Unidade +(Byte(Masculino)*2)]
            else
              Result := cnDezena[Dezena] + ' e ' +cnUnidade[Unidade];
  end else
    Result := 'zero';
end;

// Monta a hora por extenso.
// Pode receber um campo composto por data e hora, sem problemas
function HoraPorExtenso(Horario :TTime) :string;
var
  Hora,
  Minuto :integer;
begin
  Hora := Trunc(Frac(Horario) *24);  // Obtém Horas
  Minuto := Round(Frac(Frac(Horario) *24) *60);  // Obtém Minutos
  if Minuto = 60 then
  begin
    Inc(Hora);
    Minuto := 0;
  end;
  Result := DecimalExtenso(Hora, False) + ' hora';
  if Hora > 1 then
    Result := Result +'s';
  if Minuto > 0 then
  begin
    Result := Result +' e ' +DecimalExtenso(Minuto, True) +' minuto';
    if Minuto > 1 then
      Result := Result +'s'
  end;
end;
Testando a função: Para o teste adicione em um Form, um Botão, um Label e um MaskEdit. No evendo OnClick do botão coloque o código a seguir:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := HoraPorExtenso(StrToTime(MaskEdit1.Text));
end;

Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...