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                                How to post scriptsource        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                                How to post scriptsource        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                                How to post scriptsource        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                                How to post scriptsource        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                                How to post scriptsource        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