;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       TimeConvert() 
;; 
;;ACTION         Converts time formats between cTime and Kix Time 
;; 
;;AUTHOR         Glenn Barnas 
;;               Based on Rata Die algorithms of Peter Baum 
;; 
;;VERSION        2.0  - 2007/01/20 
;; 
;;HISTORY        1.0  - 2006/11/20 - Initial release 
;;               2.0  - 2007/01/20 - Enhancements & Fixes 
;;                                   Eliminated 2Gig bug, 
;;                                   Add support of negative cTime values 
;;                                   Fixed Epoch bug, allowing any date value 
;;                                   Allow numeric or string Epoch value 
;; 
;;SYNTAX         TimeConvert(CValue [, Epoch]) 
;; 
;;PARAMETERS     CValue - REQUIRED - The time value to be converted. This may 
;;               be an integer value representing the number of seconds since 
;;               the Epoch, or a Date Time string in the format YYYY/MM/DD hh:mm:ss 
;;               Given one type, the function returns the other type.  
;; 
;;               Epoch - OPTIONAL - A date string (YYYY/MM/DD format) or days value 
;;               that represents the "beginning of time". The default is 1970/1/1  
;;               (719163). To accurately specify time from the year 1, use an Epoch 
;;               value of 0. Negative Epoch values were not tested. 
;; 
;;REMARKS        This function simply changes a between date strings and cTime values 
;;               and vice-versa. Any time zone conversions should be performed 
;;               external to this function.  
;; 
;;               Validated by generating sequential date values from 1/1/1883 to 
;;               12/31/2105, a range of just over 8.5 Billion seconds. 
;; 
;;               This function does not take into account changes to the calendar 
;;               which occurred throughout history. 
;; 
;;RETURNS        Double (cTime) or String (yyyy/mm/dd hh:mm:ss) depending on conversion. 
;;               Time string in Kix format (yyyy/mm/dd hh:mm:ss) if cTime format is 
;;               provided cTime value (double) if Kix format time string is provided. 
;; 
;;DEPENDENCIES   none 
;; 
;;TESTED WITH    Kix 4.50, W2K, WXP, W2K3 
;; 
;;EXAMPLES        
;;               ; What time will it be in 15 minutes? 
;;               TimeConvert(TimeConvert(@DATE + ' ' + @TIME) + 900) 
;;               ; Specialized use of EPOCH value 
;;               ; How many seconds before 2007 US taxes are due? (or overdue??) 
;;               TimeConvert(@DATE + ' ' + @TIME, '2007/04/15') ? 
; 
Function TimeConvert($_CValue, OPTIONAL $_Epoch)
 
  Dim $_			; generic counter / increment 
  Dim $_Return			; value calculated by the engine to return to the calling routine 
  Dim $_Date, $_Time		; values used by the Date to cTime routine 
  Dim $_A, $_B, $_C, $_D, $_E	; intermediate variables used in the calendar calculation 
 
  ; Validate/Define the Epoch value 
  If VarType($_Epoch) > 1
 
    If VarType($_Epoch) = 8					; yyyy/mm/dd format 
 
      $_Epoch = Split($_Epoch, '/')
      If UBound($_Epoch) <> 2 Exit 87 EndIf			; Bad Epoch date format! 
 
      For $_ = 0 to 2
        $_Epoch[$_] = Val($_Epoch[$_])				; insure values are numeric 
      Next
 
      ; Adjust for Feb 
      If $_Epoch[1] < 3
        $_Epoch[1] = $_Epoch[1] + 12
        $_Epoch[0] = $_Epoch[0] - 1
      EndIf
 
      ; Calculate days since Year 0, accounting for leap years 
      $_Epoch = CDbl($_Epoch[2]) + (153 * $_Epoch[1] - 457) / 5 + 365 * $_Epoch[0] + $_Epoch[0] / 4 - $_Epoch[0] / 100 + $_Epoch[0] / 400 - 306
 
    EndIf
 
  Else
 
    $_Epoch = 719163						; default to 1970/1/1 
 
  EndIf
 
 
  ; perform the time conversion 
  If $_CValue + 0 = $_CValue					; convert cTime to Date/Time 
 
    $_ = $_CValue
    Dim $_CValue[5]						; Prepare CValue array to hold date/time components 
    $_CValue[5] = $_
 
    $_CValue[2]  = Int($_CValue[5]  / 86400)			; Days for DATE part 
    $_CValue[5]  = $_CValue[5] - (86400.0 * $_CValue[2])	; Remaining seconds for TIME part 
    If $_CValue[5] < 0
      $_CValue[2] =$_CValue[2] - 1				; Adjust for negative cTime values 
    EndIf
    $_CValue[2]  = $_CValue[2] + $_Epoch
 
    $_E          = $_CValue[2] + 306				; Process m/d/y values, accounting for calendar changes 
    $_D          = 100 * $_E - 25				; and leap years 
    $_A          = $_D / 3652425
    $_B          = $_A - $_A / 4
    $_CValue[0]  = (100 * $_B + $_D) / 36525
    $_C          = $_B + $_E - 365 * $_CValue[0] - $_CValue[0] / 4
    $_CValue[1]  = (5 * $_C + 456) / 153
    $_CValue[2]  = $_C - (153 * $_CValue[1] - 457) / 5
 
    If $_CValue[1] > 12						; More than 12 months? 
      $_CValue[0] = $_CValue[0] + 1				; Add a year 
      $_CValue[1] = $_CValue[1] - 12				; subtract 12 months 
    EndIf
 
    $_CValue[3]  = Int($_CValue[5]  / 3600)
    $_CValue[4]  = Int(($_CValue[5]  - $_CValue[3] * 3600) / 60)
    $_CValue[5]  = $_CValue[5] - Int($_CValue[3] * 3600) - $_CValue[4] * 60
 
    ; deal with negative cTime values 
    If $_CValue[5] < 0
      $_CValue[5] = 60 + $_CValue[5]
      $_CValue[4] = $_CValue[4] - 1
    EndIf
    If $_CValue[4] < 0
      $_CValue[4] = 60 + $_CValue[4]
      $_CValue[3] = $_CValue[3] - 1
    EndIf
    If $_CValue[3] < 0
      $_CValue[3] = 24 + $_CValue[3]
    EndIf
 
    ; format the return string 
    $_Return ='' + $_CValue[0] + '/' + right('00'+ $_CValue[1], 2) + '/' + right('00' + $_CValue[2], 2)
    $_Return = $_Return + ' ' + right('00' + $_CValue[3], 2) + ':' + right('00' + $_CValue[4], 2) + ':' + right('00'+$_CValue[5] , 2)
 
  Else							; Convert Date/Time to cTime 
 
    ; convert to array & verify correct # of fields 
    $_CValue = Split(Join(Split(Join(Split($_CValue + ':0', '/'), ' '), ':'), ' '), ' ', 6)
    If UBound($_CValue) <> 5 Exit 87 EndIf	; Bad date/time format! 
 
    ; convert to numeric values 
    For $_ = 0 to 5 $_CValue[$_] = Val($_CValue[$_]) Next
 
    If $_CValue[1] < 3
      $_CValue[1] = $_CValue[1] + 12
      $_CValue[0] = $_CValue[0] - 1
    EndIf
 
    $_Date = CDbl($_CValue[2]) + (153 * $_CValue[1] - 457) / 5 + 365 * $_CValue[0] + $_CValue[0] / 4 - $_CValue[0] / 100 + $_CValue[0] / 400 - 306
    $_Time = (Val(CDbl($_CValue[3])) * 3600) + (Val($_CValue[4]) * 60) + Val($_CValue[5])
    $_Return = (($_Date - $_Epoch) * 86400 + $_Time)
 
  EndIf
 
  ; Return the value 
  $TimeConvert = $_Return
  Exit 0
 
EndFunction