Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Funcion para obtener los minutos entre 2 Horas (https://www.clubdelphi.com/foros/showthread.php?t=90690)

darkamerico 12-08-2016 21:16:44

Funcion para obtener los minutos entre 2 Horas
 
Saludos amigos, resulta que estoy haciendo un modulo para controlar la asistencia de docentes en un Centro Pre Universitario, este modulo permitirá calcular los salarios de dichos docentes.

Tengo una tabla con los horarios del Docente:

Código SQL [-]
CREATE TABLE `horario` (
  `id_horario` int(11) NOT NULL,
  `iddocente_fk` int(11) DEFAULT NULL,
  `idcurso_fk` int(11) DEFAULT NULL,
  `id_dia` smallint(6) DEFAULT NULL,
  `hora_ini` time DEFAULT NULL,
  `hora_fin` time DEFAULT NULL,
  PRIMARY KEY (`id_horario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Y Tengo una tabla para registrar las asistencias de los docentes:

Código SQL [-]
CREATE TABLE `doc_asistencia` (
  `id_asistdocente` int(11) NOT NULL,
  `iddocenteOrig_fk` int(11) DEFAULT NULL,
  `iddocenteReemplazante_fk` int(11) DEFAULT NULL,
  `idcurso_fk` int(11) DEFAULT NULL,
  `fecha` date DEFAULT NULL,
  `nombreDia` varchar(15) DEFAULT NULL,
  `hora_entrada` time DEFAULT NULL,
  `hora_salida` time DEFAULT NULL,
  `mindif_entrada` int(11) DEFAULT NULL,
  `mindif_salida` int(11) DEFAULT NULL,
  PRIMARY KEY (`id_asistdocente`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Como puede verse aqui: Necesito grabar la hora de entrada tomando la hora del equipo y calcular la diferencia en minutos de la hora tomada del sistema con la hora de inicio de su horario, ejemplo:

Hora del Sistema: 14:02:00
Hora de Inicio Horario Docente: 14:00:00

La rutina debería arrojar -2 min (negativo) dado que se esta registrando pasados dos minutos de su hora de ingreso. Mientras que:

Hora del Sistema: 13:57:00
Hora de Inicio Horario Docente: 14:00:00

La rutina debería arrojar 3 min (positivo).

Intente usando la función HourSpan() pero no arroja el valor negativo como deseo: Aqui les muestro mi rompecabezas de codigo:

Código Delphi [-]
procedure TfrmAsistDocentes.lstHorarioActivoClick(Sender: TObject);
var
  horaIni, horaFin, horaActual: string;
  posPunto, difMinutos:integer;
begin
  if lstHorarioActivo.ItemIndex<>-1 then
  begin
    posPunto:=pos('.',lstHorarioActivo.Items[lstHorarioActivo.ItemIndex]);
    idHorarioSelected:=StrToInt(Copy(lstHorarioActivo.Items[lstHorarioActivo.ItemIndex],0,posPunto-1));
    dm.q_HorarioXID.Close;
    dm.q_HorarioXID.Params[0].AsInteger:=idHorarioSelected;
    dm.q_HorarioXID.Open;

    if(length(dm.q_HorarioXID.FieldByName('hora_ini').AsString)>0)then
    begin
      horaIni:=dm.q_HorarioXID.FieldByName('hora_ini').AsString;
      horaFin:=dm.q_HorarioXID.FieldByName('hora_fin').AsString;
      horaActual:=TimeToStr(Now);
     // if StrToTime(horaActual)-StrToTime(horaIni)>0 then
        difMinutos:=HourSpan(StrToTime(horaActual),StrToTime(horaIni));
      //else
      //  difMinutos:=MinutesBetween(StrToTime(horaActual),StrToTime(horaIni))*-1;

      if difMinutos>=0 then
        lblDifMinutos.Font.Color:=clBlue
      else
        lblDifMinutos.Font.Color:=clRed;
      lblDifMinutos.Caption:=IntToStr(difMinutos) + ' min.';
      if difMinutos>5 then
        btnRegistrarAsistDoc.Enabled:=False
      else
        btnRegistrarAsistDoc.Enabled:=True;
    end;
  end;

end;

Les agradecería mucho apoyo con este problema, pues ya me quede sin ideas.

Un Abrazo

TOPX 12-08-2016 22:33:30

Saludos,

Yo lo haría así:
Código Delphi [-]
var
  difMinutos: Extended;
...
Código Delphi [-]
  if not dm.q_HorarioXIDhora_ini.IsNull then
  begin
    difMinutos := Time() - dm.q_HorarioXIDhora_ini.AsDateTime; // TO-DO: Cambiar Time() por consulta a la bd trayendo CURRENT_TIMESTAMP.

    if difMinutos >= 0 then
    begin
      lblDifMinutos.Font.Color := clBlue;
    end
    else
    begin
      lblDifMinutos.Font.Color := clRed;
    end;

    lblDifMinutos.Caption := FormatDateTime('-hh:nn:ss.zzz', difMinutos);

    btnRegistrarAsistDoc.Enabled := (difMinutos > 5);
  end;
Pero como no sé qué versión de Delphi, ni qué componentes de acceso a base datos usa, pues puedo estar muy equivocado.

De todas maneras, espero que le sirva para guiarse.
-

darkamerico 12-08-2016 22:49:23

Detalles
 
Gracias TOPX, aqui te doy detalles de mi plataforma de desarrollo:

Delphi: 10.1 Berlin
Data Access: UniDAC 6.2.8

La pantalla con el codigo que me suministraste:

https://s10.postimg.org/ceslputeh/scr.jpg

Pero no puedo interpretar el resultado que obtuve.

Te agradecería tu ayuda amigo.

Saludos

darkamerico 12-08-2016 23:04:30

Detalles
 
Gracias TOPX, aqui te doy detalles de mi plataforma de desarrollo:

Delphi: 10.1 Berlin
Data Access: UniDAC 6.2.8

La pantalla con el codigo que me suministraste:

https://s10.postimg.org/ceslputeh/scr.jpg

Pero no puedo interpretar el resultado que obtuve.

Aqui esta el codigo:

Código Delphi [-]
procedure TfrmAsistDocentes.lstHorarioActivoClick(Sender: TObject);
var
  horaIni, horaFin, horaActual: string;
  posPunto:integer;
  difMinutos:extended;
begin
  if lstHorarioActivo.ItemIndex<>-1 then
  begin
    posPunto:=pos('.',lstHorarioActivo.Items[lstHorarioActivo.ItemIndex]);
    idHorarioSelected:=StrToInt(Copy(lstHorarioActivo.Items[lstHorarioActivo.ItemIndex],0,posPunto-1));
    dm.q_HorarioXID.Close;
    dm.q_HorarioXID.Params[0].AsInteger:=idHorarioSelected;
    dm.q_HorarioXID.Open;

    if(length(dm.q_HorarioXID.FieldByName('hora_ini').AsString)>0)then
    begin
      if radEntrada.Checked then
        difMinutos:=Time() - dm.q_HorarioXID.FieldByName('hora_ini').AsDateTime;

      if radSalida.Checked then
        difMinutos:=Time() - dm.q_HorarioXID.FieldByName('hora_fin').AsDateTime;

      if difMinutos>=0 then
        lblDifMinutos.Font.Color:=clBlue
      else
        lblDifMinutos.Font.Color:=clRed;
      lblDifMinutos.Caption:=FormatDateTime('-hh:nn:ss.zzz', difMinutos) + ' min.';
      if difMinutos>5 then
        btnRegistrarAsistDoc.Enabled:=False
      else
        btnRegistrarAsistDoc.Enabled:=True;
    end;
  end;

end;

Te agradecería tu ayuda amigo.

Saludos

TOPX 12-08-2016 23:11:18

Ciertamente, 15:44:32 - 14:40:00 no da 00:44:21.

Pero, la diferencia con lo esperado es muy poca, así que sospecho que
  • ese reloj con números verdes y la hora del equipo no están sincronizados, ó
  • la operación de resta se hizo veinte minutos antes
.
-

Fe de erratas:
Código Delphi [-]
btnRegistrarAsistDoc.Enabled := not (difMinutos > 5);

TOPX 12-08-2016 23:30:48

Un programa básico para guiarse:
Label1 tiene la hora actual
Edit1 tiene la hora a restar
Label2 tiene horas, minutos y segundos resultantes
Código Delphi [-]
unit Unit1;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  dif: Extended;
begin
  dif := Time() - StrToTime(Edit1.Text);
  Label2.Caption := FormatDatetime('hh:nn:ss', dif);

  if dif < 0 then
  begin
    Label2.Caption := '- ' + Label2.Caption;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := TimeToStr(Time()) + ' menos ';
end;

end.
Código Delphi [-]
object Form1: TForm1
  ClientHeight = 243
  ClientWidth = 527
  object Label1: TLabel
    Left = 56
    Top = 88
    Width = 31
    Height = 13
    Caption = 'Label1'
  end
  object Label2: TLabel
    Left = 384
    Top = 88
    Width = 31
    Height = 13
    Caption = 'Label2'
  end
  object Edit1: TEdit
    Left = 144
    Top = 85
    Width = 121
    Height = 21
    TabOrder = 0
    Text = '11:11:10'
  end
  object Button1: TButton
    Left = 288
    Top = 83
    Width = 75
    Height = 25
    Caption = '='
    TabOrder = 1
    OnClick = Button1Click
  end
  object Timer1: TTimer
    OnTimer = Timer1Timer
    Left = 256
    Top = 128
  end
end
-

darkamerico 12-08-2016 23:33:34

Fuentes
 
Amigo TOPX te muestro la pantalla donde se puede ver que el reloj y el sistema estan sincronizados:



Y el codigo fuente del proyecto con el script de la BD en MySQL.

http://www.mediafire.com/download/rh...Asistencia.zip

Me comentas estimado amigo

Un Abrazo

santus 12-08-2016 23:49:00

Hola.
Tal vez esto te sea mas sencillo:

http://docwiki.embarcadero.com/Libra...MinutesBetween

Ten en cuenta que solo devuelve números positivos. Deberías preguntar cual fecha es mayor e invertir los parámetros si es necesario.

Saludos.

bitbow 16-08-2016 21:39:43

Mmm por que no lo haces todo dentro de la base de datos con un procedimiento almacenado, que ahi evalue los horarios en base a una tabla maestra, en caso de que lo sigas manejando con delphi trata los time o datetime como flotantes y realizas las comparaciones.

Saludos.

darkamerico 18-08-2016 02:21:35

ok
 
Cita:

Empezado por bitbow (Mensaje 507772)
Mmm por que no lo haces todo dentro de la base de datos con un procedimiento almacenado, que ahi evalue los horarios en base a una tabla maestra, en caso de que lo sigas manejando con delphi trata los time o datetime como flotantes y realizas las comparaciones.

Saludos.

Gracias bitbow por tu apreciacion, la tomare en cuenta, un saludo

gguerrini 18-08-2016 05:33:23

Y si lo pasas a todo a minutos...
 
Buenas Buenas
Capaz que no comprendí la dificultad del problema, no sería más fácil llevar todo a minutos, después lo restas y listo
14:00 = 14*60+00 = 840
14:02 = 14*60+02 = 842
840 – 842 = -2
Existen todas las funciones en Delphi, para extraer horas, minutos y segundos. Si lo llevas tos a segundos, tenes mas precisión. Ojala que te sirva. Saludos


La franja horaria es GMT +2. Ahora son las 22:38:15.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi