Author Topic: TimeStamp  (Read 691 times)

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« on: July 14, 2011, 01:07:02 pm »


               Any of you have a function to calculate the right timestamp? I've made this function:

void TimeStamp(){
    int iSecond = GetTimeSecond();
    int iMinute = GetTimeMinute()*60;
    int iHour = (GetTimeHour()*60)*60;
    int iDay = ((GetCalendarDay()*24)*60)*60;
    int iMonth = (((GetCalendarMonth()*28)*24)*60)*60;
    int iYear = ((((GetCalendarYear()*336)*28)*24)*60)*60;

   return iSecond+iMinute+iHour+iDay+iMonth+iYear;
}


first of all, it is right that the days in a month are 28?
Secondly, this function give me bad result due to INT limitation of nwn. Take 10 as the actual year and launch the function, the right result should be 8.128.512.000, nwn have an int limitation of 2.147.483.647 (taken from the lexicon)


Any hint or correction?
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
TimeStamp
« Reply #1 on: July 14, 2011, 01:44:37 pm »


               I did my timestamp as a string variable, though I only did year/month/day/hour.  That avoids int limitations entirely.

As for your script, I don't expect it's needed to go *336 * 28.  It should probably be *336 or *28*12.
               
               

               
            

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« Reply #2 on: July 14, 2011, 02:17:45 pm »


               I've thinked too to set the variables as string, but then i can't compare two timestamps with an if/else statement '<img'>

Thanks anyway with the multiplication error, misspelling when debugging the function.. (like the void declaration)
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
TimeStamp
« Reply #3 on: July 14, 2011, 02:20:17 pm »


               http://social.biowar...4495419#4495419
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
TimeStamp
« Reply #4 on: July 14, 2011, 03:22:47 pm »


               I hadn't realized it didn't overwrite strings.  A quick look at my timestamp database put it at 2.1 megs for storing a 13 digit string.  Is it just strings it does this with, or will it do it with floats as well?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
TimeStamp
« Reply #5 on: July 14, 2011, 04:39:15 pm »


               

Failed.Bard wrote...

I hadn't realized it didn't overwrite strings. A quick look at my timestamp database put it at 2.1 megs for storing a 13 digit string. Is it just strings it does this with, or will it do it with floats as well?



It will do it with any Non-fixed length data type.  

There are only two of them that can be stored in the DB.  Strings and Objects.

All of the other ones just over write the 128 byte buffer in the original record. 

If the data type is larger or even has a chance of being larger then 182 bytes, it stores a pointer to the data in the 128 byte buffer.    When the data is overwritten with this system, it appends the new data to the end of the data file and writes a new pointer to it in the 128 byte data field.    The old data is just left where ever it was at and ingnored.
               
               

               
            

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« Reply #6 on: July 14, 2011, 05:07:31 pm »


               

Lightfoot8 wrote...

http://social.biowar...4495419#4495419


whoa, it's a long reading '<img'>

But the thread is regarding the writing of the time in the db (i don't use the bio db) and i can't reproduce that for a time stamp function (newbie with the modulo operator here!)

I think i will use the time stamp as a string variable and i will create 3 function, encode (transform actual year, month etc in a string with some special character divider) , decode (that accept what type of return) and a compare one
               
               

               


                     Modifié par Epitaffio, 14 juillet 2011 - 04:10 .
                     
                  


            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
TimeStamp
« Reply #7 on: July 14, 2011, 05:30:58 pm »


               a int is fastest and easiest unless you want to go down into microseconds you can either shift the numbers in place or multiply them. but if you multiply them start with the largest, that way you will save multiplication operations and you only need one variable.

multiplication uses a maximum range while shift is slighly faster, not any speed you will notice.
               
               

               
            

Legacy_CID-78

  • Sr. Member
  • ****
  • Posts: 261
  • Karma: +0/-0
TimeStamp
« Reply #8 on: July 14, 2011, 05:35:35 pm »


               aslong as each shift make the number larger then the max value the time part can take a simple logic test against it will work.

ie Min*60 is perfect but Min<<6 (same Min*64) will give the same result when doing compare results. you only waste some number ranges.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
TimeStamp
« Reply #9 on: July 14, 2011, 07:09:09 pm »


               The Int with multiply is best.   IT will allow you to add and subtract your time stamps from one another.    

I also note that you are multiplying your minutes by 60 to get the number of hours.   Nwn hours do not have 60 minutes in them.    The number of minutes in a nwn hour is set in the module properties.   Standard is 2.     minutes and below are real time.  hours and above are game time.
               
               

               
            

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« Reply #10 on: July 17, 2011, 07:06:43 pm »


               Ok so, after some quick testing, what do you think about to use the float instead of the int?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
TimeStamp
« Reply #11 on: July 17, 2011, 07:28:08 pm »


               My first thought is that it is pointless.   If NWN used double precision floating point values it would be mor viable.  but since NWScript only ise single precision floating point values there is too much of a chance for inaccuracy.   But to really give an opinion on it I would have to know how you where planning on encoding the date/time into the flaot, to be able to see if the 6.5 digits of precision is able to handle it or not.
               
               

               
            

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« Reply #12 on: July 17, 2011, 09:01:38 pm »


               This is my latest version of the function, with the float variables (no code tag = hate)

    float iMinPerHour = HoursToSeconds(1)/60;  //20
    float iMinPerDay = 24 * iMinPerHour;    //480
    float iMinPerMonth = 28 * iMinPerDay;   //13440
    float iMinPerYear = 12* iMinPerMonth;   //161280

    float iMinute  = IntToFloat(GetTimeMinute());        //0
    float iHour    = (GetTimeHour()+1) * iMinPerHour;      //(23+1)*20     480
    float iDay     = GetCalendarDay() * iMinPerDay;      //28*480        13440
    float iMonth   = GetCalendarMonth() * iMinPerMonth;  //12*13440      161280
    float iYear    = GetCalendarYear() * iMinPerYear;    //1305*161280   210470400

    float iTimestamp = iMinute + iHour + iDay + iMonth + iYear; //210645600


Next of each row, there is an example of the max value (for the year i think we will have only 3 digit, but for testing i've just used the 4 one). I hope it's this what you asked me (i'm not english mother language, so sometimes i misunderstand ':whistle:' )
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
TimeStamp
« Reply #13 on: July 17, 2011, 10:28:17 pm »


               

Epitaffio wrote...

This is my latest version of the function, with the float variables (no code tag = hate)

    float iMinPerHour = HoursToSeconds(1)/60;  //20
    float iMinPerDay = 24 * iMinPerHour;    //480
    float iMinPerMonth = 28 * iMinPerDay;   //13440
    float iMinPerYear = 12* iMinPerMonth;   //161280

   
Next of each row, there is an example of the max value (for the year i think we will have only 3 digit, but for testing i've just used the 4 one). I hope it's this what you asked me (i'm not english mother language, so sometimes i misunderstand ':whistle:' )


changed this section just a tad.  the -1 is to make te numbers 0 based. this makes it easier to exstract your original times back out.

 
    float iMinute  = IntToFloat(GetTimeMinute() -1 );        //0
    float iHour    = GetTimeHour()  * iMinPerHour;      //(24)*20     480
    float iDay     = (GetCalendarDay()-1 )* iMinPerDay;      //28*480        13440
    float iMonth   = (GetCalendarMonth()-1 ) * iMinPerMonth;  //12*13440      161280
    float iYear    = GetCalendarYear() * iMinPerYear;    //1305*161280   210470400
 



Yes that is what I needed.   So it looks like you are running a server with 20min/hour.  
To answer your question: no this will not work.   Here is the reasion why. 

the single precison float(32 bit) format  that nwn uses has only 6 1/2 digits of precision. this means that you can only rely on the value of the 6 most significent digits in the number.  lets look at this in relation to your number. 

If we have the date/ time

year  6
month 1
day 1
time 0:00
 your time stamp would be
   6 years *161280min/year  
+ (1-1)months  * 480min/month
+ (1-1)day *  13440min/day
+  0hour * 20min/hour
+ 0min
=  967,680min

So for 6 years we have a time stamp of 967,680 minutes.   This is no problem and within the limitations of the nwn float.   
  
lets see what year 7 looks like 
  7 years *161280min/year = 1,128,960
now we have a problem, our number is 7 digits long.   the last digit in the number only has a 50% chance of being accurate.   This means that if you added a single minute to your time stamp.  It might get add it might not.  Or it could even add 2 minutes instead of the one your where trying to add.


once you go out to year 70 you would then have  8 digits in the number and adding minutes in blocks of less the 10 would most likely have no effect on your stamp at all.   minutes in quanites of less then 100 would have inacurate results but would at least have a chance to effect the stamp.  


So the short answer here is No.   the float is a bad solution for this method,. 

the int on the other hand will give you  a number that can go all the way up to 2,147,483,648   with being accurate.  that is 9.2 digits of accuracy.  

with the method above you coud accuratly store 13,315 years into the int and  less then 7 years into the float.  
               
               

               
            

Legacy_Epitaffio

  • Jr. Member
  • **
  • Posts: 70
  • Karma: +0/-0
TimeStamp
« Reply #14 on: July 17, 2011, 11:18:30 pm »


               Hum.. i see your point

So, finally.. i can't use float for the accuracy... if i use int with seconds, i will reach the int limit.

The only solution i can see is to use int without seconds, it's right?


Just a last thing, you have corrected my script with the -1 to use a 0 based values, but in case of the first XXX, where XXX is one of the -1 value, i will have a 0 result. Why this will help me to extract the initial result? It's modulo related?