Jump to content

_DateAdd improved


Recommended Posts

hi everyone I have encountered this problem when I want to add 2 hours to a date 2021/04/19 12:00:00, I can use _DateAdd, but if I want to remove 2 hours from the date, I cannot do it with _DateDiff because it makes a difference between two date, so I modified _DateAdd, now add and subtract, I hope to please and above all to have written in the right section

bye

; #FUNCTION# ====================================================================================================================
; Author ........: Jos van der Zande
; Modified.......: faustf
; ===============================================================================================================================
Func _DateAddorSub($sType, $iNumber, $sDate, $iAddORSub= Default)
    If $iAddORSub = Default Then $iAddORSub = 0
    Local $asTimePart[4]
    Local $asDatePart[4]
    Local $iJulianDate
    ; Verify that $sType is Valid
    $sType = StringLeft($sType, 1)
    If StringInStr("D,M,Y,w,h,n,s", $sType) = 0 Or $sType = "" Then
        Return SetError(1, 0, 0)
    EndIf
    ; Verify that Value to Add  is Valid
    If Not StringIsInt($iNumber) Then
        Return SetError(2, 0, 0)
    EndIf
    ; Verify If InputDate is valid
    If Not _DateIsValid($sDate) Then
        Return SetError(3, 0, 0)
    EndIf
    ; split the date and time into arrays
    _DateTimeSplit($sDate, $asDatePart, $asTimePart)

    ; ====================================================
    ; adding days then get the julian date
    ; add the number of day
    ; and convert back to Gregorian
    If $sType = "d" Or $sType = "w" Then
        If $sType = "w" Then $iNumber = $iNumber * 7
        If $sType = "w" Then $iNumber = $iNumber * 7
        If $iAddORSub = 0 Then
            $iJulianDate = _DateToDayValue($asDatePart[1], $asDatePart[2], $asDatePart[3]) + $iNumber
        Else
            $iJulianDate = _DateToDayValue($asDatePart[1], $asDatePart[2], $asDatePart[3]) - $iNumber
        EndIf
        _DayValueToDate($iJulianDate, $asDatePart[1], $asDatePart[2], $asDatePart[3])
    EndIf
    ; ====================================================
    ; adding Months
    If $sType = "m" Then
        If $iAddORSub = 0 Then
            $asDatePart[2] = $asDatePart[2] + $iNumber
        Else
            $asDatePart[2] = $asDatePart[2] - $iNumber
        EndIf
        ; pos number of months
        While $asDatePart[2] > 12
            $asDatePart[2] = $asDatePart[2] - 12
            $asDatePart[1] = $asDatePart[1] + 1
        WEnd
        ; Neg number of months
        While $asDatePart[2] < 1
            $asDatePart[2] = $asDatePart[2] + 12
            $asDatePart[1] = $asDatePart[1] - 1
        WEnd
    EndIf
    ; ====================================================
    ; adding Years
    If $sType = "y" Then
        If $iAddORSub = 0 Then
            $asDatePart[1] = $asDatePart[1] + $iNumber
        Else
            $asDatePart[1] = $asDatePart[1] - $iNumber
        EndIf
    EndIf
    ; ====================================================
    ; adding Time value
    If $sType = "h" Or $sType = "n" Or $sType = "s" Then
        Local $iTimeVal = _TimeToTicks($asTimePart[1], $asTimePart[2], $asTimePart[3]) / 1000
        If $iAddORSub = 0 Then
            If $sType = "h" Then $iTimeVal = $iTimeVal + $iNumber * 3600
            If $sType = "n" Then $iTimeVal = $iTimeVal + $iNumber * 60
            If $sType = "s" Then $iTimeVal = $iTimeVal + $iNumber
        Else
            If $sType = "h" Then $iTimeVal = $iTimeVal - $iNumber * 3600
            If $sType = "n" Then $iTimeVal = $iTimeVal - $iNumber * 60
            If $sType = "s" Then $iTimeVal = $iTimeVal - $iNumber
        EndIf

        ; calculated days to add
        Local $iDay2Add = Int($iTimeVal / (24 * 60 * 60))
        $iTimeVal = $iTimeVal - $iDay2Add * 24 * 60 * 60
        If $iTimeVal < 0 Then
            $iDay2Add = $iDay2Add - 1
            $iTimeVal = $iTimeVal + 24 * 60 * 60
        EndIf
        $iJulianDate = _DateToDayValue($asDatePart[1], $asDatePart[2], $asDatePart[3]) + $iDay2Add
        ; calculate the julian back to date
        _DayValueToDate($iJulianDate, $asDatePart[1], $asDatePart[2], $asDatePart[3])
        ; caluculate the new time
        _TicksToTime($iTimeVal * 1000, $asTimePart[1], $asTimePart[2], $asTimePart[3])
    EndIf
    ; ====================================================
    ; check if the Input day is Greater then the new month last day.
    ; if so then change it to the last possible day in the month
    Local $iNumDays = _DaysInMonth($asDatePart[1])
    ;
    If $iNumDays[$asDatePart[2]] < $asDatePart[3] Then $asDatePart[3] = $iNumDays[$asDatePart[2]]
    ; ========================
    ; Format the return date
    $sDate = $asDatePart[1] & '/' & StringRight("0" & $asDatePart[2], 2) & '/' & StringRight("0" & $asDatePart[3], 2)
    ; add the time when specified in the input
    If $asTimePart[0] > 0 Then
        If $asTimePart[0] > 2 Then
            $sDate = $sDate & " " & StringRight("0" & $asTimePart[1], 2) & ':' & StringRight("0" & $asTimePart[2], 2) & ':' & StringRight("0" & $asTimePart[3], 2)
        Else
            $sDate = $sDate & " " & StringRight("0" & $asTimePart[1], 2) & ':' & StringRight("0" & $asTimePart[2], 2)
        EndIf
    EndIf
    ;
    Return $sDate
EndFunc   ;==>_DateAddorSub

 

Link to comment
Share on other sites

  • Moderators

faustf,

Quote

if I want to remove 2 hours from the date, I cannot do it with _DateDiff because it makes a difference between two date

Really? This works fine for me:

#include <Date.au3>

; Date string you provided
$sDate = "2021/04/19 12:00:00"
; Subtract 2 hours
$sNewdate = _DateAdd ( "h", -2, $sDate )
; And display the result
ConsoleWrite($sNewDate & @CRLF)

; Result is "2021/04/19 10:00:00"

That looks to be the correct result in my universe.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

1 hour ago, Melba23 said:

That looks to be the correct result in my universe.

Amazingly, it is the same in my universe too :lol:.

@faustf : This is exactly as described in the Help :

Parameters :

$iNumber = Number of intervals to be added/subtracted (use unary minus for subtraction)

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

1 hour ago, argumentum said:

It just feels like a useless bashing.

I would agree, except Musashi also tried to help explain why faustf was wrong :)

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

1 hour ago, argumentum said:

It just feels like a useless bashing.

My post was not intended as 'bashing' (if your comment aimed at me). I have no reason to do so.

I just wanted to additionally point out, that the help provides a good description of the respective parameter. Perhaps @faustf has overlooked this issue .

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

  • Developers
4 hours ago, faustf said:

so I modified _DateAdd, now add and subtract,

As stated by all previous posters, this UDF I wrote Many Many....Many moons ago can perfectly subtract time.
In case you think otherwise I like to see an example snippet proving me wrong. ;) 

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

He probably didnt know about negative numbers and expected a _DateSubstract function. :)

Edited by Werty
changed grin to smile

Some guy's script + some other guy's script = my script!

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...