Sign in to follow this  
Followers 0
jlandes

_datediff And _dateadd

17 posts in this topic

I'd like to include _DateAdd and _DateDiff type functions in the library with similar use as VB. However, I've run into a stump that I cannot seem to figure out the best way to do this. Does anyone here want to take a stab in writing these UDFs for inclusion in the library? If so, please e-mail me at jlandes@landeserve.com or post here. Thanks.


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites



I think in order for this to work, we'd need to standardize on the way dates and times are passed to functions. I propose that dates be passed in the format YYYY/MM/DD and times be passed in the format HH:MM:SS. It would also be helpful to have two new internal macros created called @Date and @Time. The @Date macro would return the current date (in the format YYYY/MM/DD) and the @Time macro would return the current time (in the format HH:MM:SS). Then, the _DateDiff and _DateAdd functions could use a standard format to work on getting the difference between two dates/times or adding/subtracting dates and times. What do you all think?


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

On another note, how about a @Now macro too that returns both the date and time (formatted as YYYY/MM/DD HH:MM:SS)?


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

I think in order for this to work, we'd need to standardize on the way dates and times are passed to functions.  I propose that dates be passed in the format YYYY/MM/DD and times be passed in the format HH:MM:SS.  It would also be helpful to have two new internal macros created called @Date and @Time.  The @Date macro would return the current date (in the format YYYY/MM/DD) and the @Time macro would return the current time (in the format HH:MM:SS).  Then, the _DateDiff and _DateAdd functions could use a standard format to work on getting the difference between two dates/times or adding/subtracting dates and times.  What do you all think?

What about compatibility with FileGetTime output?

Share this post


Link to post
Share on other sites

FileGetTime returns an array containing:

$array[0] = year (four digits)

$array[1] = month (range 01 - 12)

$array[2] = day (range 01 - 31)

$array[3] = hour (range 01 - 23)

$array[4] = min (range 00 - 59)

$array[5] = sec Fil(range 00 - 59)

So, that could be formatted any way you want.


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

$array[5]= sec Fil(range 00 - 59)

That's a typo in the documentation.

Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

this is still a basic script without an validation... let me know if you like the direction and i will look at put ths checks and error returns in..

The logic is based on calcutating the date to a julian date ... then do the calculation and then convert it back ( for the Date_Add function....)

; test date diff function
msgbox(0,"Test", _DateDif (@year,@mon,@mday,2004,2,6))

; test date_dd function
$TYear = 2004
$TMonth = 02
$Tday = 03
_DateAdd ($tYear,$tMonth,$tDay,600)
msgbox(0,"New date",$tMonth & "/" & $tDay & "/" & $tYear )

Func _DateAdd (Byref $SYear,Byref $SMonth,Byref $SDay,$Days2Add)
   $jd = _JulianDayNo($SYear,$SMonth,$SDay) + $Days2Add 
   _Julian2Date($jd,$SYear,$SMonth,$SDay)  
EndFunc

Func _DateDif ($SYear,$SMonth,$SDay,$EYear,$EMonth,$EDay)
   Return(_JulianDayNo($EYear,$EMonth,$EDay) - _JulianDayNo($SYear,$SMonth,$SDay)  ) 
EndFunc

Func _JulianDayNo($Year,$Month,$Day)  
   if $Month < 3 then 
      $Month = $Month + 12
      $Year = $Year -1 
   endif 
   $A = int($Year/100)
   $B = int($A/4)
   $C = 2-$A+$B
   $E = int(1461*($Year+4716)/4)
   $F = int(153*($Month+1)/5)
   $JD= $C+$Day+$E+$F-1524.5
   return ($jd)
endFunc
   
Func _Julian2Date($jd,byref $Year,byref $Month,byref $Day)
   $Z = int($JD+0.5)
   $W = int(($Z - 1867216.25)/36524.25)
   $X = int($W/4)
   $A = $Z+1+$W-$X
   $B = $A+1524
   $C = int(($B-122.1)/365.25)
   $D = int(365.25* $C)
   $E = int(($B-$D)/30.6001)
   $F = int(30.6001 * $E)
   $Day = $B-$D-$F
  ; (must get number less than or equal to 12)
   if  $E-1 < 12 then 
      $Month = $E-1
   else 
      $Month = $E-13
   endif 
   if $month < 3 then
      $Year = $C-4715; (if Month is January or February)
   else
      $Year = $C-4716;(otherwise)
   endif
EndFunc
Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I think this is a good start. I'd like to see the time be added into this as well? Agree?


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

First, I think this is one case where an Optional statement for UDFs would come in handy. Second, it might also be good cause for specifying a format for dates and times and creating a @Date, @Time, and maybe @Now macro like I've described above. What do you think?


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

think that it would help if we combine date and time like this:

_DateAdd("YYYYMMDD","HHMMSS",Days_to_day)

_DateDiff("YYYYMMDD","HHMMSS","YYYYMMDD","HHMMSS")

Would that be better to work with ?


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I think it's a good start and could easily be changed later.


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

think that it would help if we combine date and time like this:

_DateAdd("YYYYMMDD","HHMMSS",Days_to_day)

_DateDiff("YYYYMMDD","HHMMSS","YYYYMMDD","HHMMSS")

Would that be better to work with ?

Here's some info from the MSDN article for DateAdd and DateDiff that might help:

DateAdd Function

DateDiff Function


Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

I have worked a bit more on the logic of the functions to include time..

It bed time for me ... so will continue tomorrow evening.. this is what i have at the moment, but will have a closer look at the articles from mickeysoft and see if we can do something similar...

this version has a seperate _DateDif and _DateTimeDif..

By the way: i used the _TicksToTime but it was missing a Endif and also the _TicksToTime... both just befoire the endfunc...

laters..

dim $iHours,$iMinutes, $iSeconds = 0
; test date diff function
msgbox(0,"Test", _DateDif ('2004/02/05','2004/02/06'))
$tdate = _DateTimeDif ('2004/02/05', '01:00:00','2004/02/06', '01:00:01')
$Days = int($tdate)
$timeticks=round(($tdate-$Days)*86400,0)*1000
$rc = _TicksToTime( $timeticks, $iHours,$iMinutes,$iSeconds )
msgbox(0,"_DateTimeDiff", "Days:" & $Days & @lf & "Time:" & $iHours & ":" & $iMinutes & ":" & $iSeconds )


exit
; test date_dd function
$TYear = "2004"
$TMonth = "02"
$Tday = "03"
$tDate = $tYear & '/' & $tMonth & '/' & $tDay
msgbox(0,"old date",$Tdate )
_DateAdd ($tDate,5)
msgbox(0,"New date",$Tdate )

Func _DateAdd (Byref $Idate,$Days2Add)
   $iYear = Stringmid($Idate,1,4)
   $iMonth = Stringmid($Idate,6,2)
   $iDay = Stringmid($Idate,9,2)
   $jd = _JulianDayNo($iYear,$iMonth,$iDay) + $Days2Add 
   _Julian2Date($jd,$iYear,$iMonth,$iDay)
   $iDate = $iYear & '/' & $iMonth & '/' & $iDay
EndFunc

Func _DateDif ($sdate,$edate)
   $sYear = Stringmid($sdate,1,4)
   $sMonth = Stringmid($sdate,6,2)
   $sDay = Stringmid($sdate,9,2)
   $eYear = Stringmid($edate,1,4)
   $eMonth = Stringmid($edate,6,2)
   $eDay = Stringmid($edate,9,2)
   Return(_JulianDayNo($EYear,$EMonth,$EDay) - _JulianDayNo($SYear,$SMonth,$SDay)) 
EndFunc

Func _DateTimeDif ($sdate,$sTime,$edate,$Etime)
   $sYear = Stringmid($sdate,1,4)
   $sMonth = Stringmid($sdate,6,2)
   $sDay = Stringmid($sdate,9,2)
   $sHH = Stringmid($sTime,1,4)
   $smm = Stringmid($sTime,4,2)
   $sss = Stringmid($sTime,7,2)
   $eYear = Stringmid($edate,1,4)
   $eMonth = Stringmid($edate,6,2)
   $eDay = Stringmid($edate,9,2)
   $eHH = Stringmid($eTime,1,4)
   $emm = Stringmid($eTime,4,2)
   $ess = Stringmid($eTime,7,2)
   $Days_Diff = _JulianDayNo($EYear,$EMonth,$EDay) - _JulianDayNo($SYear,$SMonth,$SDay)
   $Total_Diff =  $Days_Diff + ($ehh * 3600 + $emm * 60 + $eSS)/86400 - ($shh * 3600 + $smm * 60 + $sSS)/86400  
   Return($Total_Diff) 
EndFunc

Func _JulianDayNo($Year,$Month,$Day)  
   if $Month < 3 then 
      $Month = $Month + 12
      $Year = $Year -1 
   endif 
   $A = int($Year/100)
   $B = int($A/4)
   $C = 2-$A+$B
   $E = int(1461*($Year+4716)/4)
   $F = int(153*($Month+1)/5)
   $JD= $C+$Day+$E+$F-1524.5
   return ($jd)
endFunc
   
Func _Julian2Date($jd,byref $Year,byref $Month,byref $Day)
   $Z = int($JD+0.5)
   $W = int(($Z - 1867216.25)/36524.25)
   $X = int($W/4)
   $A = $Z+1+$W-$X
   $B = $A+1524
   $C = int(($B-122.1)/365.25)
   $D = int(365.25* $C)
   $E = int(($B-$D)/30.6001)
   $F = int(30.6001 * $E)
   $Day = $B-$D-$F
  ; (must get number less than or equal to 12)
   if  $E-1 < 12 then 
      $Month = $E-1
   else 
      $Month = $E-13
   endif 
   if $month < 3 then
      $Year = $C-4715; (if Month is January or February)
   else
      $Year = $C-4716;(otherwise)
   endif
EndFunc
#include <Date.au3>

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Okay, I'll fix the _Ticks functions. Thanks for letting me know.

Also, here's an idea on standardizing the date type functions. How about passing the date and time to the functions using a single-dimensional array that consists of the following array elements:

$array[0] = year (four digits)

$array[1] = month (range 01 - 12)

$array[2] = day (range 01 - 31)

$array[3] = hour (range 00 - 23)

$array[4] = minute (range 00 - 59)

$array[5] = second (range 00 - 59)

The functions would also return the same array type, if the function is to return a date and/or time, and the return values should be zero-padded. How does this sound? Does this solve our problem?

Edited by jlandes

Sincerely yours,Jeremy Landesjlandes@landeserve.com

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

The current Func _TicksToTime in the date.au3 has a couple of bugs in it...

Think the below version works correct..

Also the _TimeToTicks is missing an EndIF before the EndFunc statement.

Func _TicksToTime( $iTicks, ByRef $iHours, ByRef $iMinutes, ByRef $iSeconds )
;==============================================
; Local Constant/Variable Declaration Section
;==============================================
  Local $iTemp

  If StringIsInt( $iTicks ) Then
    $iTicks = Round( $iTicks / 1000 )
    $iHours = int($iTicks / 3600)
    $iTicks = Mod( $iTicks, 3600 )
    $iTicks = Round( $iTicks / 1000 )
    $iMinutes = int( $iTicks / 60)
    $iSeconds = Round( Mod( $iTicks, 60 ) )
    Return 1
  Else
    SetError( 1 )
    Return 0
   endif
EndFunc
Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

oeps :whistle:

the _TicksToTime I submited yesterday still has an error in it.

It should be :

Func _TicksToTime( $iTicks, ByRef $iHours, ByRef $iMins, ByRef $iSecs )
   If StringIsInt( $iTicks ) Then
      $iTicks = Round( $iTicks / 1000 )
      $iHours = Int( $iTicks / 3600 )
      $iTicks = Mod( $iTicks, 3600 )
      $iMins = Int( $iTicks / 60 )
      $iSecs = Round( Mod( $iTicks, 60 ) )
      Return 1
   Else
      SetError( 1 )
      Return 0
   EndIf
EndFunc

Could you please update .... thanks


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0