Number Of Complete Months

Number Of Complete Months

Postby acwoo1 » Thu Dec 18, 2014 7:48 am

Hi

How do I find out how many complete months between two dates.
(eg. from 31/03/2014 to 30/09/2014)

Thanks

Regards

ACWoo
Using FWH1304+Harbour+bcc582
acwoo1
 
Posts: 173
Joined: Tue Nov 10, 2009 10:56 am

Re: Number Of Complete Months

Postby Antonio Linares » Thu Dec 18, 2014 8:26 am

ACWoo,

Please try this:

MsgInfo( Month( CToD( "30/09/2014" ) ) - Month( CToD( "31/03/2014" ) ) )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42080
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Number Of Complete Months

Postby acwoo1 » Thu Dec 18, 2014 10:07 am

Hi

Thanks for your help.

If I change it to from 31/09/2014 to 31/03/2015, I get -6.
How to get around this ?

Thanks

Regards

ACWoo
Using FHH1304+harbour+bcc582
acwoo1
 
Posts: 173
Joined: Tue Nov 10, 2009 10:56 am

Re: Number Of Complete Months

Postby Massimo Linossi » Thu Dec 18, 2014 11:28 am

if result < 0
result += 12
endif
User avatar
Massimo Linossi
 
Posts: 498
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Number Of Complete Months

Postby sambomb » Thu Dec 18, 2014 12:42 pm

acwoo1 wrote:Hi

Thanks for your help.

If I change it to from 31/09/2014 to 31/03/2015, I get -6.
How to get around this ?

Thanks

Regards

ACWoo
Using FHH1304+harbour+bcc582


Abs() ?

nVar := 1
? nVar //1
? Abs(nVar) //1

nVar := -3
? nVar //-3
? Abs(nVar) //3
Email: SamirSSabreu@gmail.com
xHarbour 1.2.3 + Fwhh 20.2
User avatar
sambomb
 
Posts: 388
Joined: Mon Oct 13, 2008 11:26 am
Location: Itaocara - RJ - Brasil

Re: Number Of Complete Months

Postby sambomb » Thu Dec 18, 2014 12:46 pm

Check this
Code: Select all  Expand view


/***************************************************************************
* Programa ....: DateTime.PRG
* Autor .......: Samir
* Date ........: 2/3/2010 às 10:30:13
* Revisado em .: 2/3/2010 às 10:30:13
*
* Classe para tratar uma Date e Time em conjunto
*
***************************************************************************/


#include 'FiveWin.ch'

CLASS TDateTime

   //-- Propriedades -----------------------------------------------------//

   //-- Atributos a serem acessados
   DATA Date                AS Date       INIT Date()       READONLY
   DATA Time                AS Character  INIT Time()       READONLY
   DATA Secs                AS Numeric    Init 0            READONLY

   //-- Uso interno da classe
   DATA nSecsMinute         AS Numeric    Init 0            HIDDEN
   DATA nSecsHour           AS Numeric    Init 0            HIDDEN
   DATA nSecsDay            AS Numeric    Init 0            HIDDEN
   DATA nSecsMonth          AS Numeric    Init 0            HIDDEN
   DATA nSecsYear           AS Numeric    Init 0            HIDDEN

   //-- Métodos ----------------------------------------------------------//

   //-- Construção
   METHOD New(cDateIni,cTimeIni)                            CONSTRUCTOR
   METHOD End()


   METHOD Absolute(dDateReference)

   //-- Uso Interno
   METHOD Verify()                                          HIDDEN
   METHOD UpdateVar()                                       HIDDEN

   //-- Modificar atributos da classe
   METHOD SetDate(dDate) INLINE ( ::Date := dDate )
   METHOD SetTime(cTime) INLINE ( ::Time := cTime, ::Secs := Secs(cTime) )

   //-- Add Time
   METHOD AddHour(nTime)                                    //PUBLIC
   METHOD AddMinute(nMinute)                                //PUBLIC
   METHOD AddSecond(nSecond)                                //PUBLIC

   //-- Add Date
   METHOD AddDay(nDay)                                      //PUBLIC
   METHOD AddMonth(nMonth)                                  //PUBLIC
   METHOD AddYear(nYear)                                    //PUBLIC

   //-- Remove Tempo
   METHOD RemHour(nTime)                                    //PUBLIC
   METHOD RemMinute(nMinute)                                //PUBLIC
   METHOD RemSecond(nSecond)                                //PUBLIC

   //-- Remove Date
   METHOD RemDay(nDay)                                      //PUBLIC
   METHOD RemMonth(nMonth)                                  //PUBLIC
   METHOD RemYear(nYear)                                    //PUBLIC

   //-- Compatibilidade ( Aceitar comandos no plural ) -------------------//

   //-- Add Tempo
   METHOD AddHours(nHour)        INLINE   ::AddHour(nHour)
   METHOD AddMinutes(nMinute)    INLINE   ::AddMinute(nMinute)
   METHOD AddSeconds(nSecond)    INLINE   ::AddSecond(nSecond)

   //-- Add Date
   METHOD AddDays(nDay)          INLINE   ::AddDays(nDay)
   METHOD AddMonths(nMonth)      INLINE   ::AddMonth(nMonth)
   METHOD AddYears(nYear)        INLINE   ::AddYear(nYear)

   //-- Remove Tempo
   METHOD RemHour(nHour)         INLINE   ::RemHour(nHour)
   METHOD RemMinutes(nMinute)    INLINE   ::RemMinute(nMinute)
   METHOD RemSeconds(nSecond)    INLINE   ::RemSecond(nSecond)

   //-- Remove Date
   METHOD RemDays(nDay)          INLINE   ::RemDay(nDay)
   METHOD RemMonths(nMonth)      INLINE   ::RemMonth(nMonth)
   METHOD RemYears(nYear)        INLINE   ::RemYear(nYear)

ENDCLASS

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD New(xDateIni,cTimeIni) CLASS TDateTime
****************************************************************************
*
* Initiate the object
* Parametros: Nenhum
* Retorno: Self (Object)
*
* Autor .......: Samir
* Date ........: 2/3/2010 às 10:30:20
*
****************************************************************************

   Default xDateIni := Date(), cTimeIni := Time()
   
   If ValType(xDateIni) = "C"
      ::Date := cTod(xDateIni)
   elseif ValType(xDateIni) = "D"
      ::Date := xDateIni
   else
      ::Date := Date()
   end
   
   ::Time := cTimeIni
   
   ::Secs := Secs(cTimeIni)

   ::nSecsMinute := 60                  //-- FIXO
   ::nSecsHour   := ::nSecsMinute * 60  //-- FIXO
   ::nSecsDay    := ::nSecsHour   * 24  //-- FIXO

   //-- Atualizar Seconds do Month/Year
   ::UpdateVar()

return Self

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD End() CLASS TDateTime
****************************************************************************
*
* Release the object from memory
* Parametros: Nenhum
* Retorno: Nil
*
* Autor .......: Samir
* Date ........: 2/3/2010 às 10:30:20
*
****************************************************************************

   Self := Nil

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD UpdateVar() CLASS TDateTime
****************************************************************************
*
* Update the second counting vars
* Parametros:
* Retorno: Nil
*
* Autor: Samir
* 2/3/2010 - 13:52:18
*
****************************************************************************

   ::nSecsMonth   := ::nSecsDay    * LastDay(::Date)
   ::nSecsYear    := ::nSecsDay    * If ( IsBissexto(::Date), 366, 365 )

return nil
/*------------------------------------------------------------------------*/

****************************************************************************
METHOD Verify() CLASS TDateTime
****************************************************************************
*
* Verify if happen and Date update based on the Seconds
* Parametros: Nenhum
* Retorno: Nil
*
* Autor .......: Samir
* Date ........: 2/3/2010 às 10:30:20
*
****************************************************************************

Local lRewind := .F.

   //-- Verify if is negative or positive
   If ::Secs < 0
   
      lRewind := .T.
     
      ::Secs := Abs(::Secs)
     
   end

   //-- Increase
   If !lRewind

      //-- Verify if increase one Day
      While ::Secs > ::nSecsDay

         ::Secs -= ::nSecsDay
         ::AddDay()

      end

      //-- Update time with the rest
      ::Time := TString(::Secs)

   //-- Decrease
   else

      //-- Verify if decrease one Day
      While ::Secs > ::nSecsDay

         ::Secs -= ::nSecsDay
         ::RemDay()

      end

      //-- If time is negative, make reference to the last day
      ::RemDay()

      //-- Update time with the rest
      ::Time := TString(::nSecsDay - ::Secs)

   end
   
   ::UpdateVar()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddHour(nHour) CLASS TDateTime
****************************************************************************
*
* Add Hour
* Parametros: nHour
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:33:57
*
****************************************************************************

   Default nHour := 1
   
   ::Secs += nHour * ::nSecsHour
   
   ::Verify()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddMinute(nMinute) CLASS TDateTime
****************************************************************************
*
* Add Minute
* Parametros: nMinute
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:30
*
****************************************************************************

   Default nMinute := 1
   
   ::Secs += nMinute * ::nSecsMinute

   ::Verify()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddSecond(nSecond) CLASS TDateTime
****************************************************************************
*
* Add Second
* Parametros: nSecond
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:58
*
****************************************************************************

local Result := nil

   Default nSecond := 1

   ::Secs += nSecond

   ::Verify()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddDay(nDay) CLASS TDateTime
****************************************************************************
*
* Add Day
* Parametros: nDay
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:37:46
*
****************************************************************************

local Result := nil, nMax := 0, nEndMonth := 0, nAux := 0, cAux := ""

   Default nDay := 1

   ::Date := ::Date + nDay

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddMonth(nMonth) CLASS TDateTime
****************************************************************************
*
* Add Month
* Parametros: nMonth
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:30
*
****************************************************************************

local Result := nil

   Default nMonth := 1

   ::Date := IncMonth(::Date,nMonth)

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD AddYear(nYear) CLASS TDateTime
****************************************************************************
*
* Add Year
* Parametros: nYear
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:58
*
****************************************************************************


local Result := nil, nDayAux := 0, nMonthAux := 0, nYearAux := 0, cDateAux := ""

   Default nYear := 1

   nDayAux      := Day(  ::Date())
   nMonthAux    := Month(::Date())
   nYearAux     := Year( ::Date())

   nYearAux += nYear

   cDateAux += StrZero(nDayAux,2)   + "/"
   cDateAux += StrZero(nMonthAux,2) + "/"
   cDateAux += StrZero(nYearAux,4)

   ::Date := CtoD(cDateAux)

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemHour(nHour) CLASS TDateTime
****************************************************************************
*
* Add Hour
* Parametros: nHour
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:33:57
*
****************************************************************************

local Result := nil

   Default nHour := 1
   
   ::Secs -= nHour * ::nSecsHour

   ::Verify()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemMinute(nMinute) CLASS TDateTime
****************************************************************************
*
* Add Minute
* Parametros: nMinute
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:30
*
****************************************************************************

local Result := nil

   Default nMinute := 1
   
   ::Secs -= nMinute * ::nSecsMinute

   ::Verify()
   
return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemSecond(nSecond) CLASS TDateTime
****************************************************************************
*
* Add Second
* Parametros: nSecond
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:58
*
****************************************************************************

local Result := nil

   Default nSecond := 1

   ::Secs -= nSecond
   
   ::Verify()

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemDay(nDay) CLASS TDateTime
****************************************************************************
*
* Add Day
* Parametros: nDay
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:37:46
*
****************************************************************************

local nMax := 0

   Default nDay := 1
   
   ::Date := ::Date - nDay
   
return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemMonth(nMonth) CLASS TDateTime
****************************************************************************
*
* Add Month
* Parametros: nMonth
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:30
*
****************************************************************************

   Default nMonth := 1
   
   ::Date := DecMonth(::Date,nMonth)

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD RemYear(nYear) CLASS TDateTime
****************************************************************************
*
* Add Year
* Parametros: nYear
* Retorno: NIL
*
* Autor: Samir
* 2/3/2010 - 10:34:58
*
****************************************************************************

local nDayAux := 0, nMonthAux := 0, nYearAux := 0, cDateAux := ""

   Default nYear := 1
   
   nDayAux      := Day(::Date())
   nMonthAux    := Month(::Date())
   nYearAux     := Year(::Date())
   
   nYearAux -= nYear
   
   cDateAux += StrZero(nDayAux,2)   + "/"
   cDateAux += StrZero(nMonthAux,2) + "/"
   cDateAux += StrZero(nYearAux,4)
   
   ::Date := CtoD(cDateAux)

return nil

/*------------------------------------------------------------------------*/

****************************************************************************
METHOD Absolute(dDateReferencia) CLASS TDateTime
****************************************************************************
*
* Obter um valor absoluto em Seconds da Date mais Time
* Parametros: dDateReferencia
* Retorno: nValorAbsoluto
*
* Autor: Samir
* 17/11/2010 - 10:51:08
*
****************************************************************************

local nValorAbsoluto := 0, nDays := 0

   Default dDateReferencia := cTod("01/01/1920")

   nDays := Abs( ::Date - dDateReferencia)

   nValorAbsoluto := nDays * ::nSecsDay

   nValorAbsoluto += ::Secs

return nValorAbsoluto
/*------------------------------------------------------------------------*/

****************************************************************************
static function IsBissexto(xDate)
****************************************************************************
*
* Verificar se um ano é bissexto ou não
* Parametros: xDate
* Retorno: lResult
*
* Autor: Samir
* 2/3/2010 - 11:15:02
*
****************************************************************************

local lResult := .T., nYear := 0

   If ValType(xDate) = "D"
      nYear := Year(xDate)
   elseif ValType(xDate) = "N"
      nYear := xDate
   elseif ValType(xDate) = "C"
      If IsDigit(xDate)
         If Len(xDate) = 2 .or. Len(xDate) = 4
            nYear := Val(xDate)
         else
            lResult := .F.
         end
      else
         lResult := .F.
      end
   else
      lResult := .F.
   end

   If lResult

      If nYear % 4 = 0 .and. nYear % 100 != 0
         lResult := .T.
      Elseif nYear % 100 = 0 .and. nYear % 400 = 0
         lResult := .T.
      Else
         lResult := .F.
      End

   else

      MsgInfo("Invalid Date parameter")
   
   end

Return lResult

/*------------------------------------------------------------------------*/

****************************************************************************
function LastDay( dDateVal )
****************************************************************************
Local nLastDay, nMonthNum, nNumDays

   If dDateVal = NIL
      dDateVal := Date()
   ElseIf Valtype( dDateVal ) == 'N'
      nMonthNum := dDateVal
   ElseIf Valtype( dDateVal ) == 'D'
      nMonthNum := Month( dDateVal )
   Else
      Return 0
   Endif

   nNumDays  := 31

   Do Case
      Case nMonthNum = 4 .or. nMonthNum = 6 .or. nMonthNum = 9 .or. ;
         nMonthNum = 11
         nNumDays := 30
      Case nMonthNum = 2
         If Year( dDateVal ) % 4 = 0 .and. Year( dDateVal ) % 100 != 0
            nNumDays := 29
         Elseif Year( dDateVal ) % 100 = 0 .and. Year( dDateVal ) % 400 = 0
            nNumDays := 29
         Else
            nNumDays := 28
         Endif
   Endcase

Return( nNumDays )

/*------------------------------------------------------------------------*/

****************************************************************************
function IncMonth(dDate, nMonth)
****************************************************************************

local Result := dDate, nDia := 0, nAno := 0, nMes := 0, cData := ""

   nDia := Day(dDate)
   nMes := Month(dDate)
   nAno := Year(dDate)

   nMes += nMonth
   nMonth := nMes

   if nMes > 12
      if nMes % 12 == 0
         nMes := 12
      else
         nMes := nMes % 12
         nAno += Trunc(nMonth / 12,0)
      end
   end

   if (AllTrim(Str(nMes,2,0)) $ "4,6,9,11") .and. nDia >= 30
      nDia := 30
   elseif (AllTrim(Str(nMes,2,0)) == "2") .and. nDia >= 28
      nDia := 28
   end

   cData := AllTrim(Str(nDia,2,0)) + '/' + AllTrim(Str(nMes,2,0)) + '/' + ;
            AllTrim(Str(nAno,4,0))

   if Empty(CTOD(cData))
      MsgAlert(cData)
   end

   Result := CtoD(cData)

Return Result

/*------------------------------------------------------------------------*/

****************************************************************************
function DecMonth(dDate, nMonth)
****************************************************************************

local Result := dDate, nDia := 0, nAno := 0, nMes := 0, cData := ""

   nDia := Day(dDate)
   nMes := Month(dDate)
   nAno := Year(dDate)

   nAno -= Trunc(nMonth / 12,0)

   nMes -= ( nMonth % 12 )

   if nMes <= 0

      if nMonth % 12 == 0
         //nMes := 12
         nMes := Month(dDate)
      else

         nAno -= 1
         nMes += 12

      end
   end

   if (AllTrim(Str(nMes,2,0)) $ "4,6,9,11") .and. nDia = 31
      nDia := 30
   elseif (AllTrim(Str(nMes,2,0)) == "2") .and. nDia >= 29
      nDia := 28
   end

   cData := AllTrim(Str(nDia,2,0)) + '/' + AllTrim(Str(nMes,2,0)) + '/' + ;
            AllTrim(Str(nAno,4,0))

   Result := CtoD(cData)

Return Result

/*------------------------------------------------------------------------*/
 
 
Email: SamirSSabreu@gmail.com
xHarbour 1.2.3 + Fwhh 20.2
User avatar
sambomb
 
Posts: 388
Joined: Mon Oct 13, 2008 11:26 am
Location: Itaocara - RJ - Brasil

Re: Number Of Complete Months

Postby acwoo1 » Thu Dec 18, 2014 1:09 pm

Hi

Thanks for your help.

How to show that the number of complete months from 31/01/2014 to 01/03/2014 is 1 instead of 2.

Thanks

Regards

ACWoo
Using FHW1304+FHW+bcc582
acwoo1
 
Posts: 173
Joined: Tue Nov 10, 2009 10:56 am

Re: Number Of Complete Months

Postby Antonio Linares » Thu Dec 18, 2014 1:46 pm

Acwoo,

MsgInfo( Month( CToD( "01/03/2014" ) ) - Month( CToD( "31/01/2014" ) ) - 1 )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42080
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Number Of Complete Months

Postby nageswaragunupudi » Sun Jan 04, 2015 9:58 pm

acwoo1 wrote:Hi

How do I find out how many complete months between two dates.
(eg. from 31/03/2014 to 30/09/2014)

Thanks

Regards

ACWoo
Using FWH1304+Harbour+bcc582


I suggest two alternative function. Both give the same result.
Code: Select all  Expand view
function MonthsLapsed_1( dDate1, dDate2 )

   local nMths

   nMths := CEILING( ( dDate2 - dDate1 ) / 30.4 )
   do while ADDMONTH( dDate1, nMths ) > dDate2
      nMths--
   enddo

return nMths
 

and
Code: Select all  Expand view
function MonthsLapsed_2( dDate1, dDate2 )

   local nMths

   nMths    := ( Year(  dDate2 ) - Year(  dDate1 ) ) * 12 + ;
               ( Month( dDate2 ) - Month( dDate1 ) )

   if Day( dDate2 ) < Day( dDate1 ) .and. dDate2 < EOM( dDate2 )
      nMths--
   endif

return nMths
 

Note: ADDMONTH(), CEILING(), EOM() are available in CT.LIB for xHarbour and HBCT.LIB for Harbour.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10624
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Number Of Complete Months

Postby nageswaragunupudi » Sun Jan 04, 2015 10:45 pm

The DateTime class is excellant and could be quite useful till DateTime datatyes were implemented in (x)Harbour.

Now that DateTime type ( "T" ) is available both for memory variables and field variables, we can straight away use these new types. The days of dealing with Dates separately and Times separately as Chracter values are gone years back.

t := DateTime()
? t // --> 05-01-2015 03:48:00

Add Hour : t += 1/24
Add Minute : t += 1/1440

Add Time 03:40:26
t += TimeToSecs( "03:40:26" ) / 86400

Add number of days : t += nDays

For adding months and years we can use the readily available function ADDMONTH() in ct.lib. Actually this function was avaialable even during 16-bit Clipper days in CA-Tools library.

nResult := ADDMONTH( dDate, (plus or minus ) nMths )
nResult := ADDMONTH( dDate, (plus or minus ) 12 * nYears )

There is one issue:
ADDMONTH() function accepts pure Date variable only. This is because this function is an implementation of the very old CA-Tools function.

We can have a small derived function to use this with DateTime values also:

Code: Select all  Expand view

function FW_ADDMONTH( tDate, nMths )

   if ValType( tDate ) == 'T'
      return FW_DTOT( ADDMONTH( FW_TTOD( tDate ), nMths ) ) + ;
             FW_TIMEPART( tDate ) / 86400
   endif

return ADDMONTH( tDate, nMths )
 

This function returns Date variable if the input is date type and DateTime variable if the input is DateTime data type.

DateTime field types:
If we are using DBFCDX rdd, we can have field type "T" for storing DateTime values.
We can have field type "=". In this case RDD automatically udpdates this field with system datetime when inserted or updated.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10624
Joined: Sun Nov 19, 2006 5:22 am
Location: India


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 63 guests