Visual Basic 6 - Trabalhando com datas


O Visual Basic 6 trata o tempo de uma maneira diferente a que estamos acostumados. Para manipular o tempo o VB utiliza o tipo de dados Date que usa o dia como unidade básica de tempo. (Leia também : Visual Basic - Datas e o ano 2000)

Assim uma hora é 1/24 avos de um dia ,um minuto a 1/1440 e um segundo é 1/86400 avos de um dia . ( legal né ...:-( ). Assim uma semana pode ser representada pelo numero de dias que a contém : 7 dias. 

Da mesma forma 0,5 horas seria 30/12/1899 12:00:00 , onde 0 corresponde a data e parte decimal 5 corresponde às horas. 

O tipo de dados Date irá exibir datas conforme a configuração local que você utilizou no seu computador. 

No calendário Juliano o primeiro dia é definido como sendo : 1 de Janeiro de 0000. Já o nosso querido VB considera o primeiro dia como sendo : 31 de dezembro de 1899. Então ele usa como base esta data para calcular todas as demais datas.

Por exemplo: o dia 04 de  dezembro de 2000 é o dia 36863 , que o número de dias contados desde 31/12/1899. Os dias anteriores a 31/12/1899 são representados como números negativos . Assim o dia 21/04/1500 esta a  -145986 dias da data 31/12/1899.

Usando o formato apropriado

Quando você for usar datas em seu código nunca as utilize como uma cadeia de caracteres( uma string) . Utilize os dados do tipo data no formato  #mês/dia/ano# e ela será interpretada de forma correta em qualquer local. Assim vejamos um exemplo:

Se um usuário informar a data 7/01/98 em uma caixa de entrada de dados:

CDate ("7/01/98")   irá retornar os seguintes resultados:

Português 07/01/98  ( sete de janeiro de 1998)
Inglês 7/1/98   (primeiro de julho de 1998)

Se você informar a mesma data usando o formato indicado (#mes/dia/ano#):

CDate(#7/1/98#)  retornará :

Português 01/07/98  ( primeiro de Julho de 1998)
Inglês 7/1/97   (primeiro de julho de 1998)

Se um usuário usando o idioma Português(Brasil) informar a data como 8/2/96 ,  a aplicação irá interpretá-la como sendo a data oito de fevereiro de 1996 , pois o formato de datas para o idioma Português é dia/mês/ano. Já um usuário nos Estados Unidos informando a mesma data terá como resultado : dois de agosto de 1996.

O formato indicado também evitará muitas dores de cabeça quanto você estiver armazenando datas em um banco de dados e utilizar consultas SQL para realizar buscas ou filtrar um recordset do seu banco de dados Vejamos um exemplo :

1-) Suponha que você tenha um banco de dados chamado base.mdb e que deseja procurar na tablela clientes por todos os clientes com data de aniversário igual a 30 de março de 1960 - 30/03/1960.  Sabendo que o campo que armazena a data de aniversário é chamado de aniv vamos montar uma consulta SQL para retornar todos os clientes com aniversário em 30/03/1960.

a-) Usando a data no formato dd/mm/aa (dd/mmyy) : Não vai funcionar ( O recordset estará vazio )

Dim db As Database
Dim rs As Recordset

Set db = OpenDatabase("base.mdb")
' tabela clients
Set rs = db.OpenRecordset("Clientes,dbopenDynaset")
' O formato da data é dd/mm/yy.
rs.FindFirst "Aniv = #30/03/60#"
...
db.Close
rs.Close 

 b-) Usando a data no formato mm/dd/aa (mm/dd/yy) : Irá funcionar em qualquer idioma.

Dim db As Database
Dim rs As Recordset

Set db = OpenDatabase("base.mdb")
' tabela clientes
Set rs = db.OpenRecordset("Clientes,dbopenDynaset")
' O formato da data é mm/dd/yy.
rs.FindFirst "Aniv = #03/30/60#"
...
db.Close
rs.Close 

Formatando datas

Quando for usar a função Format não utilize formatos do tipo dd/mm/yy ou mm/dd/yy. Prefira utilizar o formato nomeado que irá determinar qual convenção deve usar em tempo de execução. Os formatos nomeados são:

  1. General Date
  2. Long Date
  3. Short Date
  4. Long Time

Ao utilizar esses nomes a saída será baseada no idioma do usuário. Vejamos um exemplo:

MDate = #8/22/1997 5:22:20 PM#
NovaData1 = Format(MDate, "Medium Date")
NovaData2 = Format(MDate, "Short Date")
NovaData3 = Format(MDate, "Long Date")
NovaData4 = Format(MDate, "General Date")
Debug.Print NovaData1, NovaData2, NovaData3, NovaData4
a-) Vejamos o resultado para um usuário rodando este código nos Estados Unidos:
22-Aug-97 	8/22/97      Monday, August 22, 1997   		8/22/97 5:22:20 PM
b-) Este mesmo código para um usuário do Brasil terá o seguinte resultado:
22/ago/97     	22/08/97      sexta-feira, 22 de agosto de 1997         22/08/97 17:22:20
Bem , a esta altura do campeonato você deve estar se perguntando: " Quer dizer que agora eu vou 
ter que usar a data no formato mm/dd/aa nos meus aplicativos ???"  
 
Claro que não !!! você  pode usar a data no formato dd/mm/aa , mas lembre-se de alterar para o formato
mm/dd/aa quando for usar consultas SQL , para fazer isto utilize a função format. 
 
Obs: O crystal Reports usa o formato aaaa/mm/dd. Portanto se você for usar o SelectionFormula 
no Crystal Reports e isto envolver datas , você vai ter que alterar para o formato yyyy/mm/dd.
 
Outros exemplos usando a função format:
 
Dim MTime, MData, MStr
MTime = #17:04:23#
MyDate = #January 27, 1993#

' Retorna a hora do sistema no formato Longo
MStr = Format(Time, "Long Time")       	' retorna 10:18:50

' Retorna a data atual no formato Longo
MStr = Format(Date, "Long Date")  		' retorna segunda-feira, 22 de dezembro de 2000

MStr = Format(MTime, "h:m:s")   		' Retorna "17:4:23".
MStr = Format(MTime, "hh:mm:ss AMPM")   	' Retorna "05:04:23 PM".
MStr = Format(MData, "dddd, mmm d yyyy")   ' Retorna "quarta-feira, jan 27 1993"
MStr = Format(MData, "yyyymmdd") 	 	' Retorna "19930127"

' Se o formato não é fornecido , o retorno é uma string
MStr = Format(23)  			' Retorna "23".

' formato definido pelo usuário
MStr = Format(5459.4, "##,##0.00")   	' Retorna "5.459,40".
MStr = Format(334.9, "###0.00")   		' Retorna "334,90".
MStr = Format(5, "0.00%")   		' Retorna   "500,00%".
MStr = Format("OLA", "<")  		' Retorna "ola".
MStr = Format("Tudo bem", ">")  		' Retorna "TUDO BEM".
Usando as funções Time , Date , Now , Hour , Minute e Second

Para exibir a data e a hora atual é necessário verificar e obter estas informações do relógio do seu computador ; assim a função Time obtém a hora do sistema e a função Date obtém a data do sistema. Para obter a data e a hora temos a função Now. Assim resumindo:

Função  Descrição Retorno
Time variavel = Time Retorna a hora atual do sistema. Tipo de dados Variant
Date variavel = Date Retorna a data atual do sistema. Tipo  de dados Variant
Now variavel = Now Retorna a data e hora atual do sistema. Tipo de dados variant

Assim para obter os valores para a hora, data e data e hora podemos fazer assim:

Dim var1, var2, var3 as date

var1 = Date

var2 =Time

var3= Now

MsgBox var1 & " - " & var2 & " - " & var3

As funções : Date , Time e Now O resultado do processamento
Se você quiser atribuir novos valores para a data e a hora do seu sistema utilize : 
Dim Mhora as date
Mhora = #4:35:17 PM#   'atribui uma hora a variável
Time = Mhora   ' define a hora do sistema como a da sua variável
Dim mdate As Date
mdate = Format(#12/2/1995#, " dd/mm/yyyy") ´define uma nova data
Date = mdate  ´altera a data do sistema
 
A função Minute retorna um número inteiro entre 0 e 59 representando os minutos de uma determinada hora.
Assim temos:
Dim MTempo, MMinuto
MTempo = #12:35:17#   ' define um tempo
MMinuto = Minute(MTempo)   ' Retorna o valor 35
 
A função Hour retorna a hora de um determinado tempo. Assim temos:
Dim MTempo, MHora
MTempo = #12:35:17#   ' define um tempo
MHora = Hour(MTempo)   ' Retorna o valor 12
 
A função Second retorna um número inteiro entre 0 e 59 representando os segundos do minuto.Assim temos:
Dim MTempo, MSegundo
MTempo = #12:35:17#   ' define um tempo
MSegundo = Second(MTempo)   ' Retorna o valor 17

Verificando datas

Geralmente usamos uma caixa de texto para a entrada de dados , certo ?  e como fazemos para saber se um
valor informado pelo usuário é um valor que pode ser convertido para uma  data ?  Para isto podemos usar a 
função IsDate.
 
A  sintaxe é a seguinte : IsDate(expressão)
 
A função retorna True se a data pode ser convertida para uma Data.  Assim:
Dim Data, Data1,  Data2 ,  MData
Data = "February 12, 1969": Data1 = #2/12/69#: Data2 = "Hello"
MData = IsDate(Data)   ' Retorna True.
MData = IsDate(Data1)   ' Retorna True.
MData = IsDate(Data2)   ' Retorna False.
OBS : Mas cuidado a função IsDate aceita valores de formato de datas inválidos. Por exemplo para 66/9/15 IsDate 
retorna True
 
Calculando e Convertendo Datas
 
As principais funções para converter/calcular intervalo de datas no Visual Basic são:
 
DateDiff Calcula a quantidade de intervalo de tempo entre duas datas
Sintaxe: DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
interval Uma string que indica o intervalo de tempo usado para calcular a diferença entre  date1 e date2. Pode assumir os seguintes valores: d (dia) , m (mes) , q (quinzena) , h (hora), s (segundo) , n (minuto), yyyy (ano),  ww (semana) ,  w (dia da semana) .  Obrigatório
date1, date2 Duas datas para calcular a diferença.Obrigatório
firstdayofweek Indica o primeiro dia da semana. Se não for usada é assumido o Domingo. Opcional
firstweekofyear Indica a primeira semana do ano.Se não informada é assumida a semana do dia primeiro de janeiro.Opcional.

Abaixo temos um exemplo de utilização do parâmetro Interval no cálculo entre duas datas e os possíveis resultados obtidos:

Parâmetro Intervalo Expressão Resultado
"yyyy" Year DateDiff("yyyy", "7/4/76", "7/4/86") 10
"q" Quarter DateDiff("q", "7/4/76", "7/4/86") 40
"m" Month DateDiff("m", "7/4/76", "7/4/86") 120
"y" Day of year DateDiff("y", "7/4/76", "7/4/86") 3652
"d" Day DateDiff("d", "7/4/76", "7/4/86") 3652
"w" Weekday DateDiff("w", "7/4/76", "7/4/86") 521
"ww" Week DateDiff("ww", "7/4/76", "7/4/86") 521
"h" Hour DateDiff("h", "7/4/76", "7/4/86") 87648
"n" Minute DateDiff("n", "7/4/76", "7/4/86") 5258880
"s" Second DateDiff("s", "7/4/76", "7/4/86") 315532800
Vejamos agora um pequeno projeto para calcular  a diferença entre a data de nascimento e a data atual em dias, meses, anos e segundos.
  1. Inice um novo projeto no VB e no formulário padrão desenhe os seguintes controles : Uma etiqueta ( Data de Nascimento) uma Caixa de Texto ( text1.text="") e um botão de comando ( Efetua Cálculos). Veja abaixo:

  1. Insira o código abaixo no evento Validate da caixa de Texto: Aqui usamos o evento Validate da Caixa de Texto  para juntamente com a função IsDate verificar se a data é valida. Se a data for inválida o foco continua no controle (Cancel=True)
Private Sub Text1_Validate(Cancel As Boolean)
If Not IsDate(Text1.Text) Then
   MsgBox " Data Invalida !! ", vbCritical, " Erro na Data "
   Cancel = True
Else
   Data = CVDate(Text1.Text)
End If
End Sub
  1. Agora insira o código abaixo no evento Click do botão de comando:
Private Sub Command1_Click()
Dim d1, d2, d3, d4, d5 As Single

d1 = DateDiff("d", Data, Now)
d2 = DateDiff("m", Data, Now)
d3 = DateDiff("yyyy", Data, Now)
d4 = DateDiff("s", Data, Now)

Msg = " Sua idade e : " & vbCrLf
Msg = Msg & " ============================== " & vbCrLf
Msg = Msg & " Em dias : " & d1 & " dias " & vbCrLf
Msg = Msg & " Em meses : " & d2 & " meses " & vbCrLf
Msg = Msg & " Em anos : " & d3 & " anos " & vbCrLf
Msg = Msg & " Em segundos : " & d4 & " segundos " & vbCrLf

MsgBox Msg, vbOKOnly, " calculando intervalos de datas "

End Sub
  1. Em General Declarations do Formulário digite: Dim Data As Date
  2. Execute o projeto , informe uma data válida ( o sistema irá checar ) e o resultado será:

 
DatePart Retorna a parte especifica de uma data. Retorna um tipo de dado Variant.

Sintaxe :   DatePart(interval, date[,firstdayofweek[, firstweekofyear]])

Argumento Descrição
interval Uma string que representa o intervalo de tempo que você deseja retornar. Os valores possíveis são:  d (dia) , m (mes) , q (quinzena) , h (hora), s (segundo) , n (minuto), yyyy (ano). Obrigatório, ww (semana) ,  w (dia da semana)
date Representa a data que você pretende avaliar. Obrigatório
firstdayofweek Indica o primeiro dia da semana. Se não for usada é assumido o Domingo. Opcional
firstweekofyear Indica a primeira semana do ano.Se não informada é assumida a semana do dia primeiro de janeiro.Opcional.
Um exemplo de utilização desta função seria o cálculo do dia da semana ou da hora atual. Vejamos um exemplo de utilização da função DatePart :

Dim data As Date ' Declara variaveis

Dim Msg

data = InputBox("Informe a data a avaliar ( dd/mm/yyyy ):")

Msg = "Ano " & DatePart("yyyy", data) & vbCrLf
Msg = Msg & "Trimestre " & DatePart("q", data) & vbCrLf
Msg = Msg & "Mes " & DatePart("m", data) & vbCrLf
Msg = Msg & "Semana " & DatePart("ww", data) & vbCrLf
Msg = Msg & "Dia " & DatePart("d", data) & vbCrLf
Msg = Msg & "Dia da semana " & DatePart("w", data)

MsgBox Msg

Ao executar o exemplo acima e informar a data de avaliação como sendo a data : 11/12/2000 obteremos o seguinte resultado:


DateSerial Retorna uma data  para um ano , mês e dia especificados
Sintaxe :    DateSerial(year, month, day)
Argumentos Descrição
year Valor do tipo Integer. Representa um número entre 100 e 9999. Obrigatório. Valores entre 0 e 29 são interpretados como sendo os anos 2000-2029 , valores entre 30 e 99 são interpretados como os anos 1930-1999. Para representar anos fora destas faixas utilize o formato yyyy.
month Valor do tipo Integer. Representa uma expressão numérica
day Valor do tipo Integer. Representa uma expressão numérica
Dim Data  ' Tipo Variant
' Vamos atribuir a data 11 de dezembro de 2000

Data = DateSerial(00, 1 2, 11)
MsgBox " A data é : " &Data

Ao executar o projeto com o código acima iremos obter  =>   11/12/00
 
 
DateValue Retorna uma data  - tipo Variant.
Sintaxe : DateValue(date)    - date é uma expressão caractere que representa uma data entre 01/01/100 e 31/12/9999. Ou qualquer expressão que representa uma data/hora válidas.

Se a expressão utilizar incluir a informação de horas , a mesma não será exibida.

Se a parte referente ao ano da data for omitida DateValue utiliza o ano atual do seu sistema. Vejamos um exemplo de utilização de DateValue.

Dim Data
Data = DateValue("11/12/00")  

Ao executar o projeto com o código acima iremos transforma a string " 11/12/00" na data => 11/12/00

Usando o Controle Timer

O Visual Basic possui o controle Timer que lhe permite tratar eventos relacionados com o tempo. Este controle funciona como um relógio que dispara um evento programável a um certo intervalo de tempo. O  evento principal deste controle é o evento Timer.

Obs: O controle Timer é invisível em tempo de execução.

Podemos definir o intervalo no qual o evento Timer entra em ação atribuindo um valor a propriedade Interval do controle. A unidade de medida usada é o milisegundo ; assim se você quiser disparar o evento a cada segundo deve usar o seguinte valor para a propriedade Interval.

Timer1.Interval = 500

O valor máximo para a propriedade Interval é 65.535 , que indica que o máximo intervalo que
podemos usar é 65,5 segundos. 

As principais propriedades do controle Timer são:

Propriedade Descrição
Name O nome padrão é Timer1 para o primeiro controle.
Property Descreve a propriedade
Enabled Habilita ou desabilita o controle. O padrão é True.
Interval Determina,em milisegundos,  quando o evento Timer irá disparar (1 segundo = 1000).
Left A posição da margem direita do controle Timer.
Top A posição do topo da margem do controle Timer.
Para relaxar vamos criar um projeto usando o controle Timer que cria um relógio no VB. Vamos lá...

Private Sub Form_Load()
  lbl_time.Top = ScaleTop
  lbl_time.Left = ScaleLeft
  lbl_time.Width = ScaleWidth
  lbl_time.Height = ScaleHeight
End Sub
Private Sub Timer1_Timer()
If frmrelogio.WindowState = vbNormal Then
  lbl_time.Caption = CStr(Time)
  frmrelogio.Caption = Format(Date, "Long Date")
Else
  'Se o formulário for minimizado
  'a propriedade caption do formulario recebe a hora
  'e fique visivel na barra de tarefas
  frmrelogio.Caption = CStr(Time)
End If
End Sub

Execute o projeto e você deverá obter:

Um relógio em tempo real. (Que tal criar uma OCX´s para este projeto de forma a poder usá-la nos formulários Web ?)

Funções úteis para Cálculos com Datas
 
1- Ano Bissexto
 
Public Function Bissexto(intAno As Integer) As Boolean
'

' verifica se um ano é bissexto
'

Bissexto = False

  If intAno Mod 4 = 0 Then
     If intAno Mod 100 = 0 Then
        If intAno Mod 400 = 0 Then
            Bissexto = True
        End If
     Else
           Bissexto = True
     End If
  End If

End Function

A função recebe um inteiro e verifica se o ano é bissexto. Chamada : Bissexto(2000)  ' Retorna True

2- Último dia de um mês

Public Function FimdoMes(strData As String, blnSaltaMesAtual As Boolean) As String

Dim strAno As String
Dim strMes As String
Dim strDia As String
Dim strProximoDia As String

strData = Format(strData, "yyyymmdd")

strAno = Mid$(strData, 1, 4)
strMes = Mid$(strData, 5, 2)

' Pega a data e o mes atual
'

Select Case strMes
  Case "04", "06", "09", "11"
  strDia = "30"

  Case "02"
  If Bissexto(Val(strAno)) Then
     strDia = "29" 
  Else
     strDia = "28"
  End If

  Case Else
   strDia = "31"
 End Select

 FimdoMes = strAno & strMes & strDia

 If (FimdoMes = strData) And
SaltaMesAtual Then
   strProximoDia = ProximoDia(strData)
   FimdoMes = FimdoMes(strProximoDia, False)
 End If

End Function

Public Function ProximoDia(strDatea As String) As String
Dim dteData As Date
'
' Converte a data para o formato "yyyymmdd"
'
  dteData = Format(strData, "@@@@-@@-@@")
  ProximoDia = Format$(
DateAdd("d", 1, dteData), "yyyymmdd")

End Function

Esta função calcula o último dia de um mês para uma determinada data. Deve receber como parâmetros a data que você deseja calcular e um valor boleano (Verdadeiro/Falso) que irá fazer a a função considerar o mês seguinte quando a data que você informou se referir ao último dia de um mês.

Assim se você chamar a função assim:   FimdoMes("22/12/200")   o retorno será   31/12/2000.

Se você chamar a função assim:    FimdoMes("31/12/200")   o retorno será   31/01/2001.

Observe que a função utiliza a função Bissexto e uma outra função - ProximoDia - que nada mais faz do que receber uma data e acrescentar um dia á mesma . (Utiliza a função DateAdd )

2- Diferença entre horas

Se precisar calcular a diferença entre dois horários em valores inteiros , a função abaixo faz o serviço. O projeto contém dois controles maskeditbox e um botão de comando

Function CalculaHora(HrIni, HrFim) As Double
 Dim dblDifHoras As Double

   If IsNull(HrIni + HrFim) Then Exit Function
   dblDifHoras = DateDiff("n", HrIni, HrFim)
   CalculaHora = dblDifHoras / 60
End Function

Private Sub Command1_Click()
Dim x As Double

If CDate(maskini) > CDate(maskfim) Then
   MsgBox "A hora final nao pode ser inferior a hora inicial !!"
   Exit Sub
End If

x = CalculaHora(maskini.Text, maskfim.Text)

MsgBox " a diferenca é : " & x

End Sub


Cálculos com Datas e horas

Para terminar vamos mostrar como fazer alguns cálculos com datas e horas:

1-) Calculo da quantidade de horas em um determinado período:

a-) Hora inicial :  9:00 horas    Hora Final :  17:00 horas

horas_trabalhadas= format((#17:00# - #09:00#) * 24, "#0.0")
? horas_trabalhadas & " horas "

Resultado =>  8,0 horas 

b-) Hora inicial : 19:00 horas      Hora Final :  7:30 horas do outro dia

horas_trabalhadas= format((1+ #7:30# - #19:00#) * 24, "#0.0")
? horas_trabalhadas & " horas "

Resultado =>  12,5 horas 

c-) Hora inicial : 15:00 horas      Hora Final :  20:30 horas do outro dia (mais de 24 horas)

horas_trabalhadas= format((#15:00# + #20:30#) * 24, "#0.0")
? horas_trabalhadas & " horas "

Resultado =>  35,5 horas 

d-) Hora inicial : 7:00 horas      Hora Final :  21:00 horas do outro dia (mais de 24 horas)

horas_trabalhadas= format((#07:00# + #21:00#), "#0.0")
? horas_trabalhadas & " dias "

Resultado =>  1,2 dias 

Acabei... :-)

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti