Mostrando las entradas con la etiqueta Fecha y hora. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Fecha y hora. Mostrar todas las entradas

21 de septiembre de 2016

Resolución de SECONDS()

Artículo original: Resolution of SECONDS()
http://www.foxpert.com/knowlbits_200705_5.htm
Autor: Christof Wollenhaupt
Traducido por: Ana María Bisbé York


En Win 9.x, SECONDS() tiene resolución de 1 ms. En los sistemas basados en NT, SECONDS() cambia cada 10 ms, como se puede ver en el programa siguiente:

For t=1 to 100
  ? Seconds()
endfor

En NT se puede cambiar la resolución para SECONDS() utilizando la función API timeBeginPeriod:

Declare long timeBeginPeriod in WinMM.dll long
timeBeginPeriod(1)

Ahora SECONDS() incrementa cada milisegundo:

For t=1 to 100
  ? Seconds()
Endfor

22 de agosto de 2015

Día del año

Una función que retorna el correlativo del día del año de una fecha pasada como parámetro DiaDelAnio() y su inversa InvDiaDelAnio()
? DiaDelAnio(DATE())
? DiaDelAnio(DATE(2015,12,31))

? InvDiaDelAnio(1)
? InvDiaDelAnio(365)
? InvDiaDelAnio(60, 2012)


FUNCTION DiaDelAnio(tdFecha)
  *---
  * Retorna el día del año de la
  * fecha pasada como parámetro
  *---
  IF NOT VARTYPE(tdFecha)$"DT"
    tdFecha = DATE()
  ENDIF
  RETURN tdFecha - DATE(YEAR(tdFecha),1,1) + 1
ENDFUNC

FUNCTION InvDiaDelAnio(tnDia, tnAnio)
  *---
  * Retorna la fecha del día del
  * año pasado como parámetro
  * Inversa de la función DiaDelAnio()
  *---
  IF NOT VARTYPE(tnDia)$"N"
    RETURN NULL
  ENDIF
  IF EMPTY(tnAnio)
    tnAnio = YEAR(DATE())
  ENDIF
  RETURN DATE(tnAnio,1,1) + tnDia - 1
ENDFUNC
Luis María Guayán

16 de abril de 2015

Función GoWeek()

Una función definida por el usuario para sumar o restar semanas a una variable Fecha o Fecha-Hora. Similar a GoMonth(), que sirve para meses.
? GoWeek(DATETIME(), 2)
? GoWeek(DATE(), 3)
? GoWeek(DATETIME(), -3)

FUNCTION GoWeek(tuDate,tnWeeks)
  LOCAL luRet
  IF VARTYPE(tnWeeks) # "N"
    tnWeeks = 0
  ENDIF
  DO CASE
    CASE VARTYPE(tuDate) = "D"
      luRet = tuDate + tnWeeks * 7
    CASE VARTYPE(tuDate) = "T"
      luRet = tuDate + tnWeeks * 7 * 60 * 60 * 24
    CASE NOT VARTYPE(tuDate) $ "TD"
      *-- Error
      luRet = NULL
  ENDCASE
  RETURN luRet
ENDFUNC
Tomado de la función GoDay() publicada aquí.

Luis María Guayán

20 de octubre de 2011

Funciones de fechas definidas por el usuario

Un resumen de diversas funciones de fecha definidas por el usuario que complementan las funciones de Fecha que provee Visual FoxPro.

A lo largo de mi vida como desarrollador, fui acumulando diversas funciones definidas por el usuario, para distintos tipos de necesidades. En el caso de Fechas he recopilado varias funciones, (algunas fueron ya publicadas en el artículo Trabajar con fechas y horas en Visual FoxPro) que se fueron mejorando por distintos participantes de los foros que yo participo.

Aquí un resumen de funciones referidas a Meses:

* Números de días del mes (Number Days Of Month)
? nDoM(DATE(2012,2,1))

FUNCTION nDoM(tdFecha)
  RETURN DAY(GOMONTH(DATE(YEAR(tdFecha),MONTH(tdFecha),1),1)-1)
ENDFUNC 
* Principio del mes (Begin Of Month)
? BoM(DATE())

FUNCTION BoM(tdFecha)
  RETURN DATE(YEAR(tdFecha),MONTH(tdFecha),1)
ENDFUNC 
* Fin de mes (End Of Month)
? EoM(DATE())

FUNCTION EoM(tdFecha)
  RETURN GOMONTH(DATE(YEAR(tdFecha),MONTH(tdFecha),1),1)-1
ENDFUNC 
*- Fin del trimestre (End Of Quarter)
? EOQ(DATE())

FUNCTION EOQ(tdFecha)
  RETURN GOMONTH(DATE(YEAR(tdFecha),CEILING(MONTH(tdFecha)/3)*3,1),1)-1
ENDFUNC
Las siguientes funciones retornan la fecha de un día específico, como por ejemplo el primer lunes de enero, o el último domingo de febrero

*-- Tercer Domingo de Octubre de 2011
? OrdDOW(3,1,10,2011)

FUNCTION OrdDOW(tnOrd,tnDow,tnMonth,tnYear)
  * tnOrd:   1=Primero, 2=Segundo, 3=Tercero, ...
  * tnDow:   1=Domingo ... 7=Sabado
  * tnMonth: 1=Enero ... 12=Diciembre
  * tnYear:  1900 ... 9999
   RETURN DATE(tnYear,tnMonth,1)+tnOrd*7- ;
      DOW(DATE(tnYear,tnMonth,1)+tnOrd*7-1,tnDow)
ENDFUNC
* Último Miercoles de Octubre de 2011
? LastDOW(4,9,2011)

FUNCTION LastDOW(tnDow,tnMonth,tnYear)
  * tnDow:   1=Domingo ... 7=Sabado
  * tnMonth: 1=Enero ... 12=Diciembre
  * tnYear:  1900 ... 9999
  LOCAL ld
  ld = GOMONTH(DATE(tnYear,tnMonth,1),1)-1
  RETURN ld - (DOW(ld) - tnDow) % 7
ENDFUNC
Luis María Guayán

7 de febrero de 2011

Función GoDay()

Una función definida por el usuario para sumar o restar días a una variable Fecha o Fecha-Hora. Similar a GoMonth(), que sirve para meses.
? GoDay(DATETIME(),365)
? GoDay(DATE(),28)
? GoDay(DATETIME(),-31)

FUNCTION GoDay(tuDate,tnDays)
  LOCAL luRet
  IF VARTYPE(tnDays) # "N"
    tnDays = 0
  ENDIF
  DO CASE
    CASE VARTYPE(tuDate) = "D"
      luRet = tuDate + tnDays
    CASE VARTYPE(tuDate) = "T"
      luRet = tuDate + tnDays * 60 * 60 * 24
    CASE NOT VARTYPE(tuDate) $ "TD"
      *-- Error
      luRet = NULL
  ENDCASE
  RETURN luRet
ENDFUNC
Vea también: GoWeek() para semanas.

Luis María Guayán

10 de diciembre de 2007

Semana del mes

Otra opción para los compañeros que necesitan saber la semana del mes ....

ldate = DATE()
? WEEK(ldate) - (WEEK(ldate - DAY(ldate) + 1) - 1)
Ernesto Hernandez

30 de noviembre de 2007

Semanas del mes

Un compañero de trabajo hoy me estaba solicitando una rutina que le mostrara las semanas del mes así que basado en un ejemplo que existe en fox.wikis.com del ultimo día del mes lo adapte e hice la siguiente función a la cual podría ayudar a alguien como este compañero si existe una mejor forma agradecería sus comentarios.
? SEMANASMES(DATE())

FUNCTION SEMANASMES(ldFecha)
  IF TYPE("ldFecha") # "D"
    MESSAGEBOX('Parametro invalido',16,"Alto")
    RETURN 0
  ENDIF
  RETURN CEILING(DAY(GOMONTH(ldFecha, 1) - DAY(ldFecha)) / 7)
ENDFUNC
Emanuel Omar Villicaña Villegas

7 de noviembre de 2007

Rutina para una fecha en letras

Hice una variaciones para utilizar la rutina de Hector Urrutia en una función definida por el usuario (UDF) el programa puede tener cualquier nombre yo le puse datestr.prg y asi se llama la función, es como sigue:
PARAMETERS tddate
LOCAL lcStr as String
lcStr = UPPER(CDOW(tdDate)) + [, ] + ALLT(STR(DAY(tdDate))) + [ DE ] + ;
  UPPER(SUBSTR(SUBSTR(DMY(tdDate),AT(" ",DMY(tdDate),1) + 1,LEN(DMY(tdDate))),1,RAT(" ",SUBSTR(DMY(tdDate),;
  AT(" ",DMY(tdDate),1) + 1,LEN(DMY(tdDate))),1))) + [ DE ]+ ALLT(STR(YEAR(tdDate)))
RETURN lcStr 
De esta forma agrega mucha funcionalidad ya que si tenemos una tabla donde haya un campo fecha se puede ver directamente usando el browse tanto el campo fecha como su descripción en letra utilizando la función como un campo calculado por ejemplo:
BROWSE FIELD FECHA,A=DATESTR(FECHA)
también
DISP ALL FECHA,DATESTR(FECHA)
también si tienes la fecha en una variable
? DATESTR(variable)
Gracias a todos en especial a Hector mucha salud y suerte.

Nelson Maranjes
Cuba

30 de octubre de 2007

Retorna una fecha en palabras

Rutina que retorna una fecha en palabras.
*!* Retorna una fecha en palabras 
*!* USO: ? DateToStr(DATE())
FUNCTION DateToStr(tdDate as Date)
 LOCAL lcStr as String
 lcStr = UPPER(CDOW(tdDate)) + [, ] + ALLT(STR(DAY(tdDate))) + [ DE ] + ;
   UPPER(SUBSTR(SUBSTR(DMY(tdDate),AT(" ",DMY(tdDate),1) + 1,LEN(DMY(tdDate))),1,RAT(" ",SUBSTR(DMY(tdDate),;
   AT(" ",DMY(tdDate),1) + 1,LEN(DMY(tdDate))),1))) + [ DE ]+ ALLT(STR(YEAR(tdDate)))
  RETURN lcStr 
ENDFUNC 
Saludos desde El Salvador

Hector Urrutia

25 de septiembre de 2006

Inversa de DTOS(), cadenas a fechas

Muchas veces tenemos algunos datos en formato año-mes-dia (AAAAMMDD), ya sea basado en la función DTOS() (Date To String) de VFP, o provenientes de algún otro sistema/lenguaje. A continuación la forma de convertir esas cadenas a tipos de datos fecha.

Lo que tendremos que hacer es simplemente usar la evaluación en línea que ofrece VFP:
**************************************************************************
* Function: STOD()
* Convierte una cadena en formato AAAMMDD al tipo de datos Date de VFP.
* Parameters: tcFecha --> La fecha en formato AAAMMDD, de tipo caracter.
* Returns:
*      + La fecha correspondiente con tipo de datos Fecha (Date de VFP)
*      + .NULL. en caso de haber error, o no cumplir con los
*        requerimentos
* Developer: Esparta Palma 
* Uso:
*     lcFecha = "20060920" && 20 de Septiembre de 2006 como cadena
*     ldFecha = STOD(lcFecha)
**************************************************************************
    Function STOD(tcFecha)
       LOCAL ldFecha
       ldFecha = .NULL.
       IF (Vartype(tcFecha)=="C") AND (NOT EMPTY(tcFecha)) ;
           AND (NOT IsNull(tcFecha))
           TRY
              ldFecha = EVALUATE("{^"+TRANSFORM(tcFecha,"@R 9999-99-99")+"}")
           CATCH TO oError
                 ?oError.Message
                ldFecha = NULL
           ENDTRY
       ENDIF
       Return ldFecha
   EndFunc
La cuestión principal es formar la fecha en el formato necesario para evaluarla, por ello el uso de la función Transform(), la cuál, hará un cambio de por ejemplo: "20060920" a "2006-09-20", a partir de ahí sumamos los caracteres iniciales y finales, quedando una cadena (siguiendo el ejemplo): "{^2006-09-20}", solo resta aplicar una evaluación en tiempo de ejecución, con lo que así tendremos nuestro tipo de datos fecha.

Nota: El código está optimizado para VFP8 y posteriores, ya que usa el control de errores en bloques TRY..CATCH, si usas una versión anterior simplemente remueve ese bloque y usa tu propia rutina de captura de errores.

Espero les sea de utilidad.

Espartaco Palma Martínez

31 de mayo de 2006

Días comerciales entre dos fechas calendario

Esta función se llama menosd30 y la hice para calcular los días comerciales entre dos fechas.

Funciona de la siguiente manera:
? menosd30(DATE(2006,1,1), DATE(2006,12,31))
El código es el siguiente.
FUNCTION menosd30()
  PARAMETER _fi,_ff
  SET CENTURY ON
  SET DATE TO DMY
  fi=_fi
  ff=_ff
  mi=MONTH(fi)
  mf=MONTH(ff)
  di=DAY(fi)
  df=DAY(ff)
  yi=YEAR(fi)
  yf=YEAR(ff)
  xm=mf-mi
  IF di > 30 AND df > 30
    di = 30
  ENDIF
  IF df > 30
    df = 30
  ELSE
    IF MONTH(ff + 1) > MONTH(ff)
      df = 30
    ENDIF
  ENDIF
  xd=df-di+1
  xy=yf-yi
  xf=xm*30+xd+(xy*360)
  RETURN xf
ENDFUN
Nelson Cortés

30 de mayo de 2006

Fecha comercial basada en días

La función lo que hace es tomar una fecha y con base a ella calcula los días comerciales.

Esta función la llamo masd30 y funciona de la siguiente forma:
? masd30(DATE(2006,03,01),60)
El código es el siguiente :
FUNCTION masd30()
  PARAMETER _DIA,_dias
  SET CENTURY ON
  SET DATE TO DMY
  dia=_DIA
  dias=_dias
  v=30-DAY(dia)+1
  v2=dias-v
  v3=v2/30
  IF v2 = 0
    v4=30
  ELSE
    v4=MOD(v2,30)
  ENDIF
  v3=CEILING (v3)
  vf=GOMONTH(dia,v3)
  vf1=ALLTRIM(STR(v4))+"/"+PADL(ALLTRIM(STR(MONTH(vf))),2,"0")+"/"+ALLTRIM(STR(YEAR(vf)))
  vf2=CTOD(vf1)
  IF EMPTY(vf2)
    vf2="01/"+PADL(ALLTRIM(STR(MONTH(vf)+1)),2,"0")+"/"+ALLTRIM(STR(YEAR(vf)))
    vf2 = CTOD(vf2)
    vf2 = vf2 - 1
  ENDIF
  RETURN vf2
ENDFUN
Nelson Cortés

30 de diciembre de 2005

Convertir una expresión de caracteres en una expresión de fecha

Considerando que la función CTOD( ) no es segura, creé esta función para convertir una expresión de caracteres - fecha en formato corto - en una expresión de fecha.

Según la propia ayuda de VFP: "Nota: CTOD( ) puede crear valores ambiguos de fecha y generar un error de compilación...", entonces, como estoy importando datos que están en EXCEL necesité de esta función que, tal vez, pueda serle útil a otros.

Sintaxis:
StrToDate(cExpresion, cFormatoDeFecha)
Parámetros:
  • cExpresion: Especifica una expresión de caracteres.
  • cFormatoDeFecha: especifica el formato en el cual se encuetra cExpresion.
Ejemplo de uso:
? StrToDate("2004/5/30";"a/m/d")
? StrToDate("2004-5-30";"a-m-d")
? StrToDate("04.5.30","a.m.d";)
? StrToDate("30/5/4";"d/m/a")
Function StrToDate
    Lparameters lcFecha,lcFormatOrig
    Local ARRAY laFec(3)
    Local nn, lcEstr
    lcDelim = Iif(GetWordCount(lcFormatOrig,"/") = 3, "/", ;
      Iif(GetWordCount(lcFormatOrig,"-") = 3, "-", ;
      Iif(GetWordCount(lcFormatOrig,".") = 3, ".","")))
    If Empty(lcDelim)
       Return {}
       *-- puede ser mejor devolver .f. para provocar un error
    EndIf
    lcFormatOrig = Lower(lcFormatOrig) && por si acaso
    For nn = 1 to 3
        lcEstr = GetWordNum(lcFormatOrig,nn,lcDelim)
        laFec(Iif(lcEstr="a",1,Iif(lcEstr="m",2,3)))=Val(GetWordNum(lcFecha,nn,lcDelim))
    EndFor
    *-- Por si el año se haya escrito abreviado (se interpreta del siglo XXI)
    *-- se puede mejorar esta parte comprobando SET CENTURY TO ROLLOVER
    If Len(Alltrim(Str(laFec(1)))) > 4
       laFec(1)=2000 + laFec(1)
    EndIf
    Return Date(laFec(1),laFec(2),laFec(3))
EndFunc
Mario Esquivel Bado

2 de mayo de 2005

Fecha y hora de un Servidor

Con esta función podemos tomar la fecha y hora de un servidor Windows NT o superior, desde Visual FoxPro, con funciones de la API de Windows.
? ServerTime("\\MiServidor")

*----------------------------------------------------
* FUNCTION ServerTime(tcServerName, tlUtcTime)
* Retorna la hora del servidor pasado como parametro
* PARAMETROS:
*    tcServerName = Nombre del servidor
*    tlUtcTime = .T. FH UTC - .F. FH Local
* RETORNO: FechaHora ó .Null. si hubo error
* USO: ? ServerTime("\\MiServidor")
*----------------------------------------------------
FUNCTION ServerTime(tcServerName, tlUtcTime)
  IF PARAMETERS() < 2
    tlUtcTime = .F.
  ENDIF
  DECLARE INTEGER NetRemoteTOD IN netapi32 ;
    STRING @,  INTEGER @
  DECLARE INTEGER RtlMoveMemory IN win32api ;
    STRING @outbuffer, ;
    INTEGER inbuffer, ;
    INTEGER bytes2copy
  tdbuffout = REPLICATE(CHR(0), 48)
  tdbuffin = 0
  lcTryServerName = STRCONV(tcServerName, 5)
  rc = NetRemoteTOD(@lcTryServerName, @tdbuffin)
  IF rc = 0
    =RtlMoveMemory(@tdbuffout, tdbuffin, 48)
  ELSE
    lcTryServerName = STRCONV("\\" + tcServerName, 5)
    rc = NetRemoteTOD(@lcTryServerName, @tdbuffin)
    IF rc = 0
      =RtlMoveMemory(@tdbuffout, tdbuffin, 48)
    ELSE
      *-- Error con NetRemoteTOD()
      RETURN .Null.
    ENDIF
  ENDIF
  tod_month = str2long(SUBSTR(tdbuffout, 37, 4))
  tod_day = str2long(SUBSTR(tdbuffout, 33, 4))
  tod_year = str2long(SUBSTR(tdbuffout, 41, 4))
  tod_hours = str2long(SUBSTR(tdbuffout, 9, 4))
  tod_mins = str2long(SUBSTR(tdbuffout, 13, 4))
  tod_secs = str2long(SUBSTR(tdbuffout, 17, 4))
  tod_timezone = str2long(SUBSTR(tdbuffout, 25, 4)) * 60
  serverdatetime = DATETIME(tod_year, tod_month, tod_day, ;
    tod_hours, tod_mins, tod_secs)
  IF tlUtcTime
    tdServerTime = serverdatetime
  ELSE
    tdServerTime = serverdatetime - tod_timezone
  ENDIF
  RETURN tdServerTime
ENDFUNC

*----------------------------------------------------
FUNCTION str2long(tcLongStr)
  LOCAL ln, lnRetVal
  lnRetVal = 0
  FOR ln = 0 TO 24 STEP 8
    lnRetVal = lnRetVal + (ASC(tcLongStr) * (2^ln))
    tcLongStr = RIGHT(tcLongStr, LEN(tcLongStr) - 1)
  ENDFOR
  RETURN lnRetVal
ENDFUNC

*----------------------------------------------------
Esta función fue tomada y ligeramente modificada del siguiente artículo de la Base de Conocimientos de Microsoft:

-- Cómo utilizar la función NetRemoteTOD para obtener información de fecha y hora de un servidor --
http://support.microsoft.com/kb/249716

Luis María Guayán

28 de marzo de 2005

Número de día del año

Rutina para obtener el número de día del año de una fecha.
*-- Ejemplo de uso:
? DoY()                 && Hoy
? DoY(DATE(2005,2,5))   && 5 de Febrero
? DoY(DATE(2004,12,31)) && Año bisiesto

*------------------------------------------------
* FUNCTION DoY(tdFecha)
*------------------------------------------------
* Retorna el número de día del año.
* (Número de días a partir del 1° de Enero)
*------------------------------------------------
FUNCTION DoY(tdFecha)
  IF EMPTY(tdFecha)
    tdFecha = DATE()
  ENDIF
  RETURN tdFecha - DATE(YEAR(tdFecha),1,1) + 1
ENDFUNC
*------------------------------------------------
Luis María Guayán

14 de septiembre de 2004

Trabajar con fechas y horas en Visual FoxPro


Autor: Luis María Guayán

Este artículo describe las funciones nativas de Visual FoxPro y diversas funciones definidas por el usuario para el tratamiento de expresiones de tipo Date y DateTime.

Introducción

Visual FoxPro posee muchas funciones nativas que generan y manipulan expresiones de tipo Date y DateTime. En este artículo veremos las características de algunas de estas funciones y una recopilación de funciones definidas por el usuario publicadas en PortalFox que nos permitirán obtener diversos resultados a partir de este tipo de expresiones.

Funciones DATE() y DATETIME()

La función DATE() nos retorna la fecha actual del sistema si se ejecuta sin argumentos. Para evitar complicaciones con fechas ambiguas es conveniente que siempre utilicemos la función DATE(nAnio,nMes,nDia) con sus argumentos para crear expresiones de tipo Date.
dFecha = DATE()            && Fecha actual del sistema
dFecha = DATE(2000,03,01)  && 1 de Marzo de 2000 
La diferencia entre dos expresiones de tipo Date nos retorna el número de días transcurridos entre ambas fechas.
? DATE(2004,12,31) - DATE(2004,1,1) 
Si se suman o restan cantidades numéricas de días a una expresión de tipo Date, el resultado es otra expresión de tipo Date.
? DATE() + 7   && La fecha actual mas 7 días
? DATE() - 15  && La fecha actual menos 15 días 
La función DATETIME() nos retorna la fecha y hora actual del sistema si se ejecuta sin argumentos. Al igual que la función DATE() y para evitar complicaciones con fechas ambiguas es conveniente que siempre utilicemos la función DATETIME(nAnio,nMes,nDia,nHoras,nMinutos,nSegundo) con todos sus argumentos para crear expresiones de tipo DateTime.
tFHora = DATETIME()                     

&& Fecha y hora actual del sistema
tFHora = DATETIME(2000,03,01,16,15,30)  && 1 de Marzo de 2000, 16:15:30 horas 
La diferencia entre dos expresiones de tipo DateTime nos retorna el número de segundos transcurridos entre ambas fechas y horas.
? DATETIME(2004,12,31,23,59,59) - DATETIME(2004,12,31,6,0,0)
NOTA: Debido a un bug con el redondeo en las fracciones de segundos en variables del tipo DateTime es conveniente redondear las diferencias de estas variables con ROUND(lnSeg,0)
? ROUND(DATETIME(2004,12,31,23,59,59) - DATETIME(2004,12,31,6,0,0), 0)
Si se suman o restan cantidades de segundos a una expresión de tipo DateTime, el resultado es una expresión de tipo DateTime.
? DATETIME() + 60    && Fecha y hora actual mas 60 segundos
? DATETIME() - 3600  && Fecha y hora actual menos 3600 segundos
Si deseamos generar expresiones Date y DateTime "vacías" lo hacemos de la siguiente manera:
dFecha = {}      && Expresion Date 

vacia
dFecha = {//}    && Expresion Date vacia
tFHora = {/:}    && Expresión DateTime vacia
tFHora = {//::}  && Expresión DateTime vacia 
En estos últimos ejemplos, se debe tener en cuenta que la mayoría de los servidores de bases de datos no trabaja con el concepto de fechas "vacías" como lo hace Visual FoxPro. En estos casos se debe utilizar fechas nulas debido a que se tendrán fechas incoherentes y/o no esperadas.
dFecha = .null.
tFHora = .null.

Funciones con expresiones Date y DateTime

Se pueden convertir expresiones de tipo Date a DateTime y viceversa con las funciones DTOT() y TTOD() respectivamente. En el caso de la función DTOT() (al igual que si omitimos los argumentos de horas en la función DATETIME(nAnio,nMes,nDia)) la hora se sustituye por 00:00:00 (12:00:00AM).
dFecha = DATE(2004,06,03)
tFHora = DATETIME(2004,05,18,11,30,45)
? DTOT(dFecha)
? TTOD(tFHora) 
Las siguientes funciones de Visual FoxPro sirven para poder extraer algunos valores de las expresiones Date y DateTime, como el año, el mes, el día, la semana, etc.
dFecha = DATE(2004,06,03)
tFHora = DATETIME(2004,05,18,11,30,45)
? YEAR(dFecha)     && Año de una expresión Date o DateTime
? MONTH(tFHora)    && Mes de una expresión Date o DateTime
? DAY(dFecha)      && Día de una expresión Date o DateTime
? HOUR(tFHora)     && Horas de una expresión DateTime
? MINUTE(tFHora)   && Minutos de una expresión DateTime
? SEC(tFHora)      && Segundos de una expresión DateTime
? DOW(dFecha)      && Número del día de la semana de una expresión Date o DateTime
? WEEK(dFecha)     && Número de semana del año de una expresión Date o DateTime
? QUARTER(tFHora)  && Trimestre del año de una expresión Date o DateTime 
Todas las funciones anteriores retornan valores numéricos.
Otras funciones de Visual FoxPro retornan cadenas de caracteres a partir de expresiones Date o DateTime, como por ejemplo:
dFecha = DATE(2004,06,03)
tFHora = DATETIME(2004,05,18,11,30,45)
? CMONTH(dFecha)  && Nombre del mes de una expresión Date o DateTime
? CDOW(tFHora)    && Nombre del día de la semana de una expresión Date o DateTime
? DMY(tFHora)     && Cadena con el formato día-mes-año de una expresión Date o DateTime
? MDY(tFHora)     && Cadena con el formato mes-día-año de una expresión Date o DateTime
? TTOC(tFHora)    && Convierte una expresión DateTime a caracter 
? DTOC(dFecha)    && Convierte una expresión Date a caracter 
Para retornar una cadena de caracteres solo con la hora de una variable DateTime se utiliza la función TTOC() con el segundo parámetro igual a 2.
? TTOC(DATETIME(),2) 
En Visual FoxPro se puede retornar una fecha con "n" meses anteriores o posteriores de una expresión Date o DateTime con la función GOMONTH().
? GOMONTH(DATE(),3)        

&& Tres meses después a partir de la fecha actual
? GOMONTH(DATETIME(),-12)  && Doce meses anteriores a partir de la fecha y hora actual 

Otras funciones con argumentos de expresiones Date y DateTime


10 de septiembre de 2004

Meses entre 2 fechas

Con esta simple rutina puedes determinar cuantos meses hay entre 2 fechas.
FUNCTION MesesEntreFechas(pdFecha2, pdFecha1)
  LOCAL lnAnio AS INTEGER, lnMes AS INTEGER
  lnAnio = YEAR(pdFecha2) - YEAR(pdFecha1)
  lnMes = MONTH(pdFecha2) - MONTH(pdFecha1)
  RETURN ((lnAnio * 12) + lnMes)
ENDFUNC
Jose Matute

20 de julio de 2004

Número de semana

A pesar de que existe la función nativa WEEK() que retorna el número de la semana del año, esta no satisfacía una necesidad que se me presentó, por lo que elaboré la función SEMANA() y su inversa.

Mi necesidad, era la de agrupar una consulta de todo un año, por el número de la semana. Aunque en la función WEEK() se puede especificar por ejemplo si la primer semana del año contiene el 1° de Enero, y cual será el primer día de la semana; ésta puede retornar el mismo valor para la primer semana de Enero como para la última semana de Diciembre, lo que me causaba un problema en el agrupado de mi consulta.
*-- Ejemplo de WEEK()
? WEEK(DATE(2004,1,2),1,1) && Primer semana de Enero de 2004
? WEEK(DATE(2004,12,29),1,1) && Ultima semana de Diciembre de 2004
La diferencia de la función WEEK() con la función SEMANA(), es que ésta última no retorna resultados repetidos para los meses de Enero y Diciembre.
*-- Ejemplo de SEMANA()
? SEMANA(DATE(2004,1,2),1) && Primer semana de Enero de 2004
? SEMANA(DATE(2004,12,29),1) && Ultima semana de Diciembre de 2004
A continuación, el código de las funciones SEMANA() e INVSEMANA(), ejemplos de uso y las diferencias entre WEEK() y SEMANA().
*-- Diferencias entre WEEK() y SEMANA()
ld = DATE(2004,12,15)
FOR ln = 1 TO 30
  ? ld, WEEK(ld,1,1), Semana(ld,1)
  ld = ld + 1
ENDFOR

*-- Ejemplo de INVSEMANA()
FOR ln = 1 TO 7
  ld = InvSemana(3,2005,ln,1)
  ? ld, CDOW(ld)
ENDFOR  

*------------------------------------------------------------
* FUNCTION Semana(tdFecha, tnPriDiaSem)
*------------------------------------------------------------
* Retorna el número de semana de una Fecha
* USO: Semana(DATE(2004,06,03),2)
* PARAMETROS:
*    tdFecha     = Fecha
*    tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Numérico
*------------------------------------------------------------
FUNCTION Semana(tdFecha, tnPriDiaSem)
  IF EMPTY(tdFecha)
    RETURN 0
  ENDIF
  IF EMPTY(tnPriDiaSem)
    tnPriDiaSem = 1
  ENDIF
  RETURN INT((tdFecha - DATE(YEAR(tdFecha),1,1) + ;
    7 - DOW(tdFecha,tnPriDiaSem)) / 7) + 1
ENDFUNC

*------------------------------------------------------------
* FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
*------------------------------------------------------------
* Retorna una fecha a partir de un número de semana
* USO: InvSemana(23,2004,5,2)
* PARAMETROS:
*    tnSemana    = Número de semana
*    tnAnio      = Año de la semana
*    tnNroDiaSem = Número del día de la semana (1=Domingo, ..., 7=Sábado)
*    tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Fecha
*------------------------------------------------------------
FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
  IF EMPTY(tnAnio)
    tnAnio = YEAR(DATE())
  ENDIF
  IF EMPTY(tnNroDiaSem)
    tnNroDiaSem = 1
  ENDIF
  IF EMPTY(tnPriDiaSem)
    tnPriDiaSem = 1
  ENDIF
  RETURN DATE(tnAnio,1,1) + (tnSemana * 7) - 7 + ;
    tnNroDiaSem - DOW(DATE(tnAnio,1,1),tnPriDiaSem)
ENDFUNC
*------------------------------------------------------------
Hasta la próxima.

Luis María Guayán

5 de julio de 2004

Obtener la hora del sistema local en formato de 12 horas (AM/PM)

Por diseño, la función TIME() devuelve la hora del sistema local en formato de 24 horas, pero si deseas mostrarla en formato de 12 (AM/PM) hay que hacer algunos pasitos más, aquí te mostramos una función para realizarlo.

La siguiente función se hace necesaria debido a que la función Time() (nativa de VFP) no se ve afectada por la configuración de SET HOURS, la función TTOC() actúa diferente...
*********************************************************
* Function......: GetTime
* Description...: Get the current time of the local machine with 12 hours format (AM/PM)
* Parameters....: none
* Returns......: Character [11 bytes len]
* Date.........: 28-June-2004
* Autor.........: Esparta Palma    esparta[arroba]softhome.net
* Comments...: To get the time with 24 hours, use native VFP Time() function.
*********************************************************
Function GetTime
    LOCAL lcOldHours,;    && Last Hours setting
          lcRetValue       &&Return Value

    *** Save last setting of hours
    lcOldHours = SET("HOURS")
    *** Set the new Hours setting 12 hours (AM/PM)
    SET HOURS TO 12
    *** Get the time of the current Datetime
    lcRetValue = TTOC(DATETIME(),2)
    *** Set the hours setting to the saved setting
    SET HOURS TO &lcOldHours
    RELEASE lcOldHours
    Return lcRetValue
EndFunc
Espero les sea de utilidad.

Espartaco Palma

12 de abril de 2004

Clase para calcular la edad con Años, Meses y Días

El MVP Turco, Cetin Bazos nos ofrece una excelente clase para calcular la edad, separando además, los años, meses y días, en propiedades.
Local birthDate,loCalculator
birthDate = DATE(1990,06,28)

loCalculator = Createobject("AgeCalculator")
loCalculator.CalcAge(birthDate,DATE(2010,01,31)) && Age in Jan 31,2010
? PrintAge(loCalculator,birthDate,DATE(2010,01,31))
loCalculator.CalcAge(birthDate) && Age today
? PrintAge(loCalculator,birthDate,Date())

Function PrintAge
  Lparameters loAge, ldBirthDate, ldTarget
  Local lcText
TEXT to m.lcText textmerge noshow
Birthday: [<<Transform(m.ldBirthDate,\@YL')>>]  Target date: [<<Transform(m.ldTarget,\@YL')>>]
<<m.loAge.Years>> Years,<<m.loAge.Months>> Months,<<m.loAge.Days>> Days old
ENDTEXT
  Return m.lcText
Endfunc

Function TestCalcBDateAccuracy
  Create Cursor datedata ;
    (dod D, dobS D Null, nyears i, nmonths i, ndays i, ;
    ncyears i, ncmonths i, ncdays i, DiffDays i)
  =Rand(-1)
  loCalculator = Createobject("AgeCalculator")
  For i = 1 To 1000000
    dod = Date() - Int(Iif(i <= 500000, 1000, 10000) * Rand())
    nyears = Int(99 * Rand() + 1)
    nmonths = Int(11 * Rand() + 1)
    ndays = Int(364 * Rand() + 1)
    dobS = loCalculator.CalcBDate(m.dod, m.nyears, m.nmonths, m.ndays)
    loCalculator.CalcAge(m.dod,m.dobS)
    ncyears = loCalculator.Years
    ncmonths = loCalculator.Months
    ncdays = loCalculator.Days
    DiffDays = loCalculator.GetDifference(m.dobS,;
      m.nyears, m.nmonths, m.ndays, ;
      m.ncyears, m.ncmonths, m.ncdays)
    Insert Into datedata From Memvar
  Endfor
  Select * From datedata Where DiffDays <> 0 Order By DiffDays Desc
Endfunc

Define Class AgeCalculator As Custom
  Years = 0
  Months = 0
  Days = 0

  * Calculate age with given birthDate and target calculation date
  * Target calculation date defaults to 'Today' if omitted
  * CalcAge(birthDate[, targetDate])
  Procedure CalcAge
    Lparameters tdBirth, tdTarget
    Local ldTemp, ldBirth, lnDrop
    tdTarget = Iif(Empty(m.tdTarget), Date(), m.tdTarget)
    If m.tdBirth > m.tdTarget
      ldTemp   = m.tdTarget
      tdTarget = m.tdBirth
      tdBirth  = m.ldTemp
    Endif

    ldBirth = Date(Year(m.tdTarget),Month(m.tdBirth),Day(m.tdBirth))
    lnDrop = 0
    If Empty(m.ldBirth) && leap case
      ldBirth = Date(Year(m.tdTarget),3,1)
      lnDrop = Iif(Month(m.tdTarget)<=2,0,1)
    Endif
    With This
      .Years = Year(m.tdTarget) - Year(m.tdBirth) - ;
        (Iif(m.ldBirth > m.tdTarget,1,0))
      .Months = (Month(m.tdTarget) - Month(m.tdBirth) + 12 - ;
        (Iif(Day(m.tdBirth)>Day(m.tdTarget),1,0)))%12
      ldTemp = Date( Year(m.tdBirth) + .Years, Month(m.tdBirth), Day(m.tdBirth) )
      If Empty(ldTemp)
        ldTemp = Date( Year(m.tdBirth) + .Years, Month(m.tdBirth), Day(m.tdBirth-1) )
      Endif
      .Days = m.tdTarget - Gomonth(m.ldTemp,.Months) - m.lnDrop
    Endwith
  Endproc

  * Calculate birthDate from given date, years, months, days
  * Question was raised originally by Jim Livermore on UT
  * If grandma died on:
  * Jan 1st, 1908
  *     and she was 83 years, 2 months, 5 days
  * when she died what is her BirthDate
  * CalcBDate(targetDate, years, months, days)

  * Depending on passed values accuracy is => 98.6%
  * With randomly generated 1 million values
  * Less than 14000 calculated birthdates'
  * difference from CalcAge() result is in the range 1 to -3 days
  * Check test routine at top
  Procedure CalcBDate
    Lparameters tdTarget,tnYears,tnMonths,tnDays
    Local ldDate,ldBirth
    ldDate = m.tdTarget-m.tnDays
    If Month(m.ldDate)=2 And Day(m.ldDate)=29
      ldDate = Gomonth(m.ldDate,-m.tnMonths)
      ldBirth = Date(Year(m.ldDate)-m.tnYears,Month(m.ldDate),Day(m.ldDate))
    Else
      ldBirth = Gomonth(;
        Date(Year(m.ldDate)-m.tnYears,;
        Month(m.ldDate),Day(m.ldDate)), -m.tnMonths)
    Endif
    Return m.ldBirth
  Endproc

  * Verification routines
  * Used to check the accuracy of CalcBDate
  Procedure GetDifference
    Lparameters tdBirth, tnYears1,tnMonths1,tnDays1, tnYears2,tnMonths2,tnDays2
    With This
      Return ;
        .DatesAdd(m.tdBirth, m.tnYears1,m.tnMonths1,m.tnDays1) - ;
        .DatesAdd(m.tdBirth, m.tnYears2,m.tnMonths2,m.tnDays2)
    Endwith
  Endproc

  Procedure DatesAdd
    Lparameters tdDate, tnYears,tnMonths,tnDays
    Local ldDate
    ldDate = Date(Year(m.tdDate)+m.tnYears,Month(m.tdDate),Day(m.tdDate))
    If Empty(m.ldDate)
      ldDate = Date(Year(m.tdDate)+m.tnYears,2,28)
    Endif
    Return (Gomonth(m.ldDate,m.tnMonths)+m.tnDays)
  Endproc
Enddefine
Autor: Çetin Basöz
Editor: Esparta Palma