Page 1 of 1

add 3 milliseconds to timestamp

Posted: Fri Apr 21, 2006 8:17 am
by DSguru2B
Hi guys,
I wanted advice on adding 3 milli secs. to a timestamp of length 23 and scale 3.
I can do this with a basic routine which substrings the different literals in a timestamp (year, month, day, hour, min, secs and milli secs.)
But is that the best way to go about doing it. This query is more like confirming the way i am heading and if you can give me any more suggestions.

in.tp = 09/21/2005 12:31:39.656
out.tp = 09/21/2005 12:31:39.659

Why i am thinking of writing a routine is because, the tp can also be
12/31/2005 23:59:59.997

Am i heading in the right direction :?: :?: :?:

Posted: Fri Apr 21, 2006 10:01 am
by kcbland
Yes you are. DS doesn't have a date+time manipulation facility, so writing your own function is great. Checkout this for a headstart:
viewtopic.php?t=85788

Posted: Fri Apr 21, 2006 10:25 am
by DSguru2B
I thought so. I have already started building it. I am almost half way there.
Thanks Ken.

Posted: Fri Apr 21, 2006 10:50 am
by DSguru2B
Got it to work. It handles all scenarios. Even leap years. Thanks Ken.

Posted: Fri Apr 21, 2006 10:56 am
by kcbland
Well paste it here for us all to share!! :lol:

Posted: Fri Apr 21, 2006 11:04 am
by DSguru2B
Most Definately.
But dont you guys laugh at my data structures.

Code: Select all


*** CURRENTLY THE ROUTINE ONLY HANDLES TIMESTAMP OF FORMAT YYYY/MM/DD HH:MM:SS.sss




      x = trim(Arg1)
     
      ***INITIALIZE VARIABLES
      Hr = 0
      Mn = 0
      Sc = 0
      Ms = 0

      Date = ''
      NewSc = ''
      NewMn = ''
      NewHr = ''
      InDate = ''
      NewDate = ''

      MsChk = 0
      ScChk = 0
      MnChk = 0
      HrChk = 0

      ***SUBSTRING DIFFERENT LITERALS IN TIME
      
      Hr = x[12,2]
      Mn = x[15,2]
      Sc = x[18,2]
      Ms = x[21,3]

    ***CHANGE THE ICONV TO HANDLE OTHER DATE FORMATS
      Date = x[1,10]
      InDate = Iconv(Date,"D/YMD[4,2,2]")



      ***CHECK FOR LIMITS

      MsChk = 1000 - (Ms + 3)
      ScChk = 60 - (Sc + 1)
      MnChk = 60 - (Mn + 1)
      HrChk = 24 - (Hr + 1)



      IF (MsChk <= 0)
      THEN
         GOTO AddCascade:
      END
      Else
         GOTO SimpleAdd:
      END

**THIS FUNCTION IS CALLED IF ADDITION OF 3 MILLI SECONDS
**DOES NOT TOUCH OR 999

SimpleAdd:

      Ans = Date:' ':Hr:':':Mn:':':Sc:'.':(Ms + 3)
      RETURN(Ans)





**THIS FUNCTION IS CALLED IF ADDITION OF 3 MILLI SECONDS
**EXCEEDS 999. 

AddCascade:



      IF (ScChk = 0)
      THEN

         NewSc = '00'
         IF (MnChk = 0)
         THEN

            NewMn = '00'
            IF (HrChk = 0)
            THEN

               NewHr = '00'
               NewDate = InDate + 1

            END

            ELSE
               NewHr = Hr + 1
               NewDate = InDate
            END

         END

         ELSE
            NewMn = Mn + 1
            NewHr = Hr
            NewDate = InDate
         END

      END

      ELSE
         NewSc = Sc + 1
         NewMn = Mn 
         NewHr = Hr 
         NewDate = InDate
      END

      Ans = OCONV(NewDate,"D/YMD[4,2,2]"):' ':NewHr:':':NewMn:':':NewSc:'.':'00':Abs(MsChk)
      
      RETURN(Ans)
enjoy.
:P

Posted: Fri Apr 21, 2006 3:32 pm
by ray.wurlod
When you review/enhance this, handle the case yyyy-12-31 23:59:59.998 + 0.003

Posted: Mon Apr 24, 2006 7:05 am
by DSguru2B
Ray,
I did not exaclty get your case.
Do you mean the date in that format or the case yyyy/12/31 23:59:59.998 and add .003 secs to it ???
If that latter then that has already been tested and the routine can handle that???
Can you please elaborate???

Posted: Mon Apr 24, 2006 4:52 pm
by ray.wurlod
What I meant was that you should include this case in your test data.

Does your routine work properly if the increment is negative? (Does it need to?) Try always to create re-usable components; in this case that suggests a second argument (milliseconds) for your function.

Meaningfully named arguments are always to be recommended, as they aid future developers. You can add description for each argument on the Arguments tab.

Posted: Tue Apr 25, 2006 6:45 am
by DSguru2B
Well Ray, all the test scenarios accomodating to our requirements have been satisfied. No, currently the routine just handles adding three millisecs. to the timestamp which is hardcoded in the routine.
I will definately enhance it to take in a second argument which is the milli secs to be added. I can even echance it to accept a third argument that identifies what argument 2 needs to be added in, mins, secs, hrs. etc
I can certainly make it more flexible.
Thanks Ray for your comments.
Regards,

Posted: Fri Apr 28, 2006 9:31 am
by DSguru2B
I finally got the time to enhance my routine. Now it can handle much more than just adding 3 milliseconds to the timestamp.

The revised routine handles timestamp manipulation
Routine(Arg1,Arg2,Arg3)

Arg1 = Timestamp in the format (YYYY/MM/DD HH:MM:SS.sss) eg: 2004/12/31 23:59:59.999
Arg2 = Number to be added
Arg3 = The type of manipulation needed.

Available options for Arg3:

MSEC or msec : For millisecond manipulation
SS or ss : For second manipulation
MM or mm : For minutes manipulation
DD or dd : For days manipulation

Can handle negative numbers as Arg2 too.

Code: Select all


*** CURRENTLY THE ROUTINE ONLY HANDLES TIMESTAMP OF FORMAT YYYY/MM/DD HH:MM:SS.sss

      InTimeStamp = trim(Arg1)
      NumToAdd = Abs(trim(Arg2))
      Type = UPCASE(trim(Arg3))

*-----------------------------------------------------------
*INITIALIZE VARIABLES
*-----------------------------------------------------------      

      Date = ''
      InDate = ''
      NewDate = ''
      Result = ''
      Ans = ''


*-----------------------------------------------------------
*Substring different literals of timestamp.
*----------------------------------------------------------- 

      MilliSecPart = InTimeStamp[21,3]

      Date = InTimeStamp[1,10]
      Time = InTimeStamp[12,8]
      InDate = ICONV(Date,"D/YMD[4,2,2]")
      InTime = ICONV(Time,"MTS")


*-----------------------------------------------------------
*Determine type of manipulation
*----------------------------------------------------------- 


      Begin Case

         Case Type='MSEC'

            GOTO AddMilliSec:

         Case Type='SS'

            ChgNum = NumToAdd
            GOTO TimeCalc:

         Case Type='MM'

            ChgNum = NumToAdd*60
            GOTO TimeCalc:

         Case Type='HH'

            ChgNum = NumToAdd*60*60
            GOTO TimeCalc:

         Case Type='DD'

            GOTO AddDay:

         Case 1
            Ans = "Error: Not a valid option for Arg3"
            Return(Ans)
      End Case


*-----------------------------------------------------------
* This Function Manipulates MilliSeconds.
*-----------------------------------------------------------

AddMilliSec:

      MillisecChk = Field((MilliSecPart + NumToAdd)/1000,".",1)
      AddCasMillSec = Field((MilliSecPart + NumToAdd)/1000,".",2)
      FmtMillSec = FMT(AddCasMillSec,"3'0'L")



*-----------------------------------------------------------
* Add Cascasde of Milliseconds
*-----------------------------------------------------------


      IF (MillisecChk <> 0)
      THEN

         NewTime = InTime + MillisecChk

         If (NewTime < 86399)
         Then
            NewDate = InDate
         End
         Else
            NewDate = InDate + 1
         End

         Ans = OCONV(NewDate,"D/YMD[4,2,2]"):' ':OCONV(NewTime,"MTS"):".":FmtMillSec

         RETURN(Ans)
      END

*-----------------------------------------------------------
* Simple Add of MilliSeconds
*-----------------------------------------------------------

      Else
         NewDate = InDate
         NewTime = InTime
         Ans = OCONV(NewDate,"D/YMD[4,2,2]"):' ':OCONV(NewTime,"MTS"):".":FmtMillSec
         Return(Ans)
      END

*-----------------------------------------------------------
* This Function Manipulates Hours, Minutes and Seconds
*-----------------------------------------------------------

TimeCalc:

      NewTime = InTime + ChgNum

      If (NewTime < 86399)
      Then
         NewDate = InDate
      End
      Else
         NewDate = InDate + 1
      End

      Ans = OCONV(NewDate,"D/YMD[4,2,2]"):' ':OCONV(NewTime,"MTS"):".":MilliSecPart

      Return(Ans)


*-----------------------------------------------------------
* This Function Adds Days.
*-----------------------------------------------------------

AddDay:

      NewDate = InDate + NumToAdd
      Ans = OCONV(NewDate,"D/YMD[4,2,2]"):' ':OCONV(InTime,"MTS"):".":MilliSecPart
      Return(Ans)

Just wanted to share it with you guys. Any more suggestions would be greatly appreciated.

Posted: Mon Oct 20, 2008 8:45 am
by Nisusmage
Hello All,

I'm battling to add years together.
Is there anyway I can expand on this to add years.?

I currently have a problem like this.

maturity_date = commencement_date + term_years

I suppose what I'm really looking for is this function above to add years as well, but the numbers won't be right because of leap years, etc.

Please help.

Posted: Mon Oct 20, 2008 9:23 am
by chulett
:!: Start your own post. You've jumped on the end of a resolved thread about adding milliseconds, which has nothing to do with your issue.