...

View Full Version : Checking javascript date calculation



isak
09-21-2011, 11:42 PM
I have a javascript that should convert any date into a number between 1 and 260. Based on the outcome of that calculation, a viewer is directed to a specific web page.

How can I verify the calculation? How can I see what number javascript is arriving at so I can backtrack to the error? It is not serving up the correct page.

I have compared the results to a calculator on another website (http://www.starroot.com/cgi/daycalc.pl) that uses a different script to calculate the same result -- that's why I am saying the end results are not correct.

On the other website, scroll down to where you enter a date. It returns a name just above the date (example: July 25, 1970 returns Electric Star). The script I included above returns Yellow Sun. July 25, 1970 should = 68.



function calculate() {
if(!isValidDate())
return;

var result = 0;
var cuttingAge = 260;
var yearBox = document.getElementById("year");
var year = yearBox.value;
var month = document.getElementById("month").value;
var day = document.getElementById("day").value;

//Rule # 1
if(month==1 || month==2){
var selectedYearIndex;
for(var i=0; i<yearBox.options.length; i++){
if(yearBox.options[i].selected){
selectedYearIndex = i;
break;
}
}
year = yearBox.options[selectedYearIndex-1].value;
}

//Rule # 2
var monthLength = new Array();
monthLength[0]=0;
monthLength[1]=31;
monthLength[2]=29;
monthLength[3]=31;
monthLength[4]=30;
monthLength[5]=31;
monthLength[6]=30;
monthLength[7]=31;
monthLength[8]=31;
monthLength[9]=30;
monthLength[10]=31;
monthLength[11]=30;
monthLength[12]=31;
monthLength[13]=31;
monthLength[14]=29;

var dayPassed = 0;
var tempMonth = month;
if(month<3) //If its january or february
tempMonth = parseInt(tempMonth) +12; //Add previous year's days
for(var i=3; i<tempMonth; i++){
dayPassed += monthLength[i];
}
dayPassed += parseInt(day) -1;
dayPassed = dayPassed%cuttingAge;

//Rule # 3
result = parseInt(year) + parseInt(dayPassed);

//Rule # 4
if(result > cuttingAge)
result -= cuttingAge;

//Rule # 5
var pendant = new Array();
var abc = new Array();
pendant[0] = {
name:"imix",
values:new Array(1, 21, 41, 61, 81, 101, 121, 141, 161, 181, 201, 221, 241)
};
pendant[1] = {
name:"ik",
values:new Array(2, 22, 42, 62, 82, 102, 122, 142, 162, 182, 202, 222, 242)
};
pendant[2] = {
name:"akbal",
values:new Array(3, 23, 43, 63, 83, 103, 123, 143, 163, 183, 203, 223, 243)
};
pendant[3] = {
name:"kan",
values:new Array(4, 24, 44, 64, 84, 104, 124, 144, 164, 184, 204, 224, 244)
};
pendant[4] = {
name:"chicchan",
values:new Array(5, 25, 45, 65, 85, 105, 125, 145, 165, 185, 205, 225, 245)
};
pendant[5] = {
name:"cimi",
values:new Array(6, 26, 46, 66, 86, 106, 126, 146, 166, 186, 206, 226, 246)
};
pendant[6] = {
name:"manik",
values:new Array(7, 27, 47, 67, 87, 107, 127, 147, 167, 187, 207, 227, 247)
};
pendant[7] = {
name:"lamat",
values:new Array(8, 28, 48, 68, 88, 108, 128, 148, 168, 188, 208, 228, 248)
};
pendant[8] = {
name:"muluk",
values:new Array(9, 29, 49, 69, 89, 109, 129, 149, 169, 189, 209, 229, 249)
};
pendant[9] = {
name:"oc",
values:new Array(10, 30, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230, 250)
};
pendant[10] = {
name:"chuen",
values:new Array(11, 31, 51, 71, 91, 111, 131, 151, 171, 191, 211, 231, 251)
};
pendant[11] = {
name:"eb",
values:new Array(12, 32, 52, 72, 92, 112, 132, 152, 172, 192, 212, 232, 252)
};
pendant[12] = {
name:"ben",
values:new Array(13, 33, 53, 73, 93, 113, 133, 153, 173, 193, 213, 233, 253)
};
pendant[13] = {
name:"ix",
values:new Array(14, 34, 54, 74, 94, 114, 134, 154, 174, 194, 214, 234, 254)
};
pendant[14] = {
name:"men",
values:new Array(15, 35, 55, 75, 95, 115, 135, 155, 175, 195, 215, 235, 255)
};
pendant[15] = {
name:"cib",
values:new Array(16, 36, 56, 76, 96, 116, 136, 156, 176, 196, 216, 236, 256)
};
pendant[16] = {
name:"caban",
values:new Array(17, 37, 57, 77, 97, 117, 137, 157, 177, 197, 217, 237, 257)
};
pendant[17] = {
name:"etznab",
values:new Array(18, 38, 58, 78, 98, 118, 138, 158, 178, 198, 218, 238, 258)
};
pendant[18] = {
name:"cauac",
values:new Array(19, 39, 59, 79, 99, 119, 139, 159, 179, 199, 219, 239, 259)
};
pendant[19] = {
name:"ahau",
values:new Array(20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260)
};

var redirecctPages = new Array();
redirecctPages["chuen"] = "http://store.mayankin.com/blue-monkey/";
redirecctPages["eb"] = "http://store.mayankin.com/yellow-human/";
redirecctPages["ben"] = "http://store.mayankin.com/red-skywalker/";
redirecctPages["ix"] = "http://store.mayankin.com/white-wizard/";
redirecctPages["men"] = "http://store.mayankin.com/blue-eagle/";
redirecctPages["cib"] = "http://store.mayankin.com/yellow-warrior/";
redirecctPages["caban"] = "http://store.mayankin.com/red-earth/";
redirecctPages["etznab"] = "http://store.mayankin.com/white-mirror/";
redirecctPages["cauac"] = "http://store.mayankin.com/blue-storm/";
redirecctPages["ahau"] = "http://store.mayankin.com/yellow-sun/";
redirecctPages["imix"] = "http://store.mayankin.com/red-dragon/";
redirecctPages["ik"] = "http://store.mayankin.com/white-wind/";
redirecctPages["akbal"] = "http://store.mayankin.com/blue-night/";
redirecctPages["kan"] = "http://store.mayankin.com/yellow-seed/";
redirecctPages["chicchan"] = "http://store.mayankin.com/red-serpent/";
redirecctPages["cimi"] = "http://store.mayankin.com/white-world-bridger/";
redirecctPages["manik"] = "http://store.mayankin.com/blue-hand/";
redirecctPages["lamat"] = "http://store.mayankin.com/yellow-star/";
redirecctPages["muluk"] = "http://store.mayankin.com/red-moon/";
redirecctPages["oc"] = "http://store.mayankin.com/white-dog/";

var pendantName;
for(var i =0; i<pendant.length; i++){
var found = false;
for(var j=0; j<pendant[i].values.length; j++){
if(result == pendant[i].values[j]){
pendantName = pendant[i].name;
found = true;
break;
}
}
if(found)
break;
}

document.location = redirecctPages[pendantName];
}

/**
* Comment
*/
function isValidDate() {
var year = document.getElementById("year").value;
var month = document.getElementById("month").value;
var day = document.getElementById("day").value;
if(month==2 && day>29){
alert("Please select a valid date");
return false
}
if((month==4 || month==6 || month==9 || month==11) && day>30){
alert("Please select a valid date");
return false
}

return true;
}

Old Pedant
09-22-2011, 04:11 AM
Maybe if you explained the algorithm it would help.

Is this a simple 260 day cycle? So that after day number 260 *immediately* comes day number 1? With no gaps and no repeats?

If so, then your code is way overly complex.

For what it's worth, your code looks very wrong to me.

You only handle going back one year, at most.

Old Pedant
09-22-2011, 04:23 AM
Come to think of it...

None of this makes sense, as all you pass along to the next page is the page itself...not the cycle number within that page.

That is, you would send 28 and 48 and 68 all to the same page, but then once you got on that page, how would you know if the number that got you there was 28 or 48 or 68???

It just seems very very wrong and very incomplete.

Old Pedant
09-22-2011, 04:41 AM
Here... your code much much much simplified:


<html>
<head>
<script type="text/javascript">
var pendant = [
["imix" , 1, "red-dragon/"],
["ik" , 2, "white-wind/"],
["akbal" , 3, "blue-night/"],
["kan" , 4, "yellow-seed/"],
["chicchan" , 5, "red-serpent/"],
["cimi" , 6, "white-world-bridger/"],
["manik" , 7, "blue-hand/"],
["lamat" , 8, "yellow-star/"],
["muluk" , 9, "red-moon/"],
["oc" ,10, "white-dog/"],
["chuen" ,11, "blue-monkey/"],
["eb" ,12, "yellow-human/"],
["ben" ,13, "red-skywalker/"],
["ix" ,14, "white-wizard/"],
["men" ,15, "blue-eagle/"],
["cib" ,16, "yellow-warrior/"],
["caban" ,17, "red-earth/"],
["etznab" ,18, "white-mirror/"],
["cauac" ,19, "blue-storm/"],
["ahau" ,20, "yellow-sun/"]
];

var base = "http://store.mayankin.com/"

function calculate()
{
var form = document.forms[0];
var year = Number(form.year.value);
var month = Number(form.month.value) - 1;
var day = Number(form.day.value);
if ( year == 0 || isNaN(year) || isNaN(month) || isNaN(day) )
{
alert("Please enter only numbers for the date");
return;
}
var check = new Date( year, month, day, 12, 0, 0 ); // make it noon
if ( check.getMonth() != month )
{
alert("That is not a valid date...try again.");
return;
}
// bias the number of ticks by a bunch
var msPerDay = 24 * 60 * 60 * 1000;

var ticks = check.getTime() + 500 * 365 * 31 * msPerDay;

var bias = -38; // adjust as needed

var daynum = Math.floor( ticks / msPerDay ) + bias

// then get that number mod 260:
var mod260 = daynum % 260;

// and then the actual sign/page comes from that mod 20:
var mod20 = mod260 % 20;
var offset = Math.floor( mod260 / 20 ) + 1
var choice = pendant[mod20];
var page = base + choice[2];

alert("Number is " + ( mod260 +1 )
+ "\nPendant is " + choice[0] + " with an offset of " + offset
+ "\nGoing to page " + page );
}
</script>
</head>
<body>
<form>
MM / DD / YYYY<br/>
<input name="month" size="1">/<input name="day" size="1">/<input name="year" size="3">
<br/>
<input type="button" value="test" onclick="calculate(this.form);">
</form>
</body>
</html>

isak
09-22-2011, 06:25 AM
Is it possible to essentially omit February 29? The following is the general rule for that date:

If you were born on February 29 before noon local time, use February 28.
If you were born after noon local time, use March 1

Old Pedant
09-22-2011, 05:40 PM
Not as I understand the Mayan calendar system.

It counts every day, in 260 day cycles.

It's unaware of the vagaries of our modern calendar system.

In other words, there's nothing special about Feb 29th.

And in any case, you clearly wouldn't omit Feb 29th of the year the person was born. Or any 4 years thereafter.

Old Pedant
09-22-2011, 05:43 PM
You still haven't answered the question about cycle number.

You get to the "yellow star" page, just fine, but then you don't know if it is "yellow ELECTRIC star" or "yellow SOLAR star". In short, your system seems really inadequate compared to the other one you showed.

isak
09-22-2011, 06:12 PM
Not true. The specific date Februray 29 IS omitted. You can see that on the calculator here (http://www.starroot.com/cgi/daycalc.pl). If you are born on that date, we refer you to the date before or after based on the time of your birth.

In this application, we are simply determining the main energy of a particular date: the color and the seal. Similar to an astrological sign, if you will. We are not interested in SOLAR, MAGNETIC, etc, here.

Old Pedant
09-22-2011, 06:51 PM
Yes, but that's just because the Mayan calendar doesn't recognize the existence of February 29th. If you wanted to do it according to the Mayan calendar, you wouldn't use month names such as "February" or "May" or any of the others, at all.

The whole thing is a hack and a hoax and worthless except for the fun factor. Do it however you wish.

isak
09-22-2011, 08:05 PM
So it's your answer that we cannot omit February 29th from the calculation?

Old Pedant
09-22-2011, 08:11 PM
I am totally lost.

You mean you want to omit it from *EVERY* year????

Huh...I guess so.

I tested out that other site and indeed they show the same response for Feb 28, 1996, as they do for Feb 29, 1996.

Seems utterly bogus, to me.

Okay, forget I said anything. I guess you do have to do the ugly subtractions, as you were doing them.

Seems to me like a gross misinterpretation of the Maya calendar system, but then what do I know. I'm just a mathematician.

isak
09-22-2011, 08:21 PM
lol... and I am just a grunt doing a job.

That said, the original script is still not returning the right answer because it includes leap year and I don't know how to remove it.

xelawho
09-22-2011, 08:28 PM
being that I'm not a mathematician or particularly knowledgeable about the Mayan calendar and that I don't really understand the code that anybody has posted so far, possibly my contribution here will not be major, but...

isn't the simplest thing to do just to grab a date before anybody who is living now was born (let's say jan 1 1880) find out what day it was on that day according to one of the 5 billion mayan calendar calculators on the web and then start the 13 day, 20 month cycle from there so that really in the end Feb 29 doesn't matter because all the code will be doing is calculating how many days have passed since that day back in 1880 (which is what my vague understanding of what the Mayans did was anyway)?

or is that what we're trying to avoid?

Old Pedant
09-22-2011, 08:48 PM
Concept:

Find what day number (0 to 259...or 1 to 260, but easier to use 0 to 259) that December 31, 1499, is. (Or any other date farther back that you will accept requests for. But Dec 31, xx99 would be easiest.)

Let's just say that Dec 31, 1499, is day 132 on the Mayan calendar (no idea what it really is...just making an example).

Then subtract 1500 from the user's give year.

7/25/1970 ==>> means 1970 - 1500 == 470.

Add 365 times that year difference to the day number for Dec 31, 1499.

132 + ( 470 * 365 ) ==>> 171682

Then add on the days of the months for all months UP TO but NOT INCLUDING the target month. For July 25th, you'd add on 31 + 28 + 31 + 30 + 31 + 30

==>> 171863

NOTICE THAT FEBRUARY IS ALWAYS 28! This takes care of your leap year problem.

Then add on the day of the month:

171863 + 25 ==>> 171888

Now take that number MODULO 260. (In JS code, 171888 % 260 )

==>> 28 !!!

Presto, you have the day number for 7/25/1970. (Okay, it should be 68, right? So just add 40 to the value for Dec 31, 1499! That is, start with 172 instead of 132. Except you really want 67! because it's easier to work with 0 to 259 than 1 to 260. So add 39 and start with 171.)

Finally, to get the right sign, you need that number (67) modulo 20.

67 % 20 ==>> 7

And the cycle number in that sign you get using floor:

Math.floor( 67 / 20 )

*********

PHEW!

Give it a shot.

Old Pedant
09-22-2011, 08:52 PM
isn't the simplest thing to do just to grab a date before anybody who is living now was born (let's say jan 1 1880) find out what day it was on that day according to one of the 5 billion mayan calendar calculators on the web and then start the 13 day, 20 month cycle from there so that really in the end Feb 29 doesn't matter because all the code will be doing is calculating how many days have passed since that day back in 1880 (which is what my vague understanding of what the Mayans did was anyway)?

That is *MY* understanding, too. And I'm 90% sure that's the right way.

But for some reason, all these modern Mayan interpreters seem to think that we should always skip Feb 29th as if the day never exists.

I really think that's brain dead. The Mayan's (a) didn't have the concept of leap years or leap days and (b) even if they did, they wouldn't have had one leap day ever 1460 days [4 of our current years].

So the whole modern updating of the Mayan cycle and prediction system and and and is utterly and totally bogus, but any reasonable interpretation.

But w.t.h. Give the suckers what they want, I guess.

devnull69
09-22-2011, 09:04 PM
Amen ... and we are not yet talking about Astrology :-)

isak
09-22-2011, 09:21 PM
You have lost me.

The idea is for people to enter their birthdate. The calculation will take them to a page where they can order a pendant that represents their "astrological" sign (i.e., mayan energy). Therefore I doubt 1499 or 1880 will be applicable here.

My job is to plug the script into a design and make this happen. The script I have been given does not produce the correct result. I do not know how to fix it. So I came here for help.

I do not understand the last info OldPendant submitted.

Old Pedant
09-22-2011, 09:52 PM
*sigh*

We start from a date in that past so we can be sure we get all dates that people might enter.

Xelawho and I agree that you are doing it all wrong, but so is that other site you pointed to, so who cares? It's all bogus anyway.

Anyway, here is my bogus calculation put into code:


<html>
<head>
<script type="text/javascript">
var pendant = [
["imix" , 1, "red-dragon/"],
["ik" , 2, "white-wind/"],
["akbal" , 3, "blue-night/"],
["kan" , 4, "yellow-seed/"],
["chicchan" , 5, "red-serpent/"],
["cimi" , 6, "white-world-bridger/"],
["manik" , 7, "blue-hand/"],
["lamat" , 8, "yellow-star/"],
["muluk" , 9, "red-moon/"],
["oc" ,10, "white-dog/"],
["chuen" ,11, "blue-monkey/"],
["eb" ,12, "yellow-human/"],
["ben" ,13, "red-skywalker/"],
["ix" ,14, "white-wizard/"],
["men" ,15, "blue-eagle/"],
["cib" ,16, "yellow-warrior/"],
["caban" ,17, "red-earth/"],
["etznab" ,18, "white-mirror/"],
["cauac" ,19, "blue-storm/"],
["ahau" ,20, "yellow-sun/"]
];

var base = "http://store.mayankin.com/"

var monthDays = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 ];

function calculate()
{
var form = document.forms[0];
var year = Number(form.year.value);
var month = Number(form.month.value) - 1;
var day = Number(form.day.value);
if ( year == 0 || isNaN(year) || isNaN(month) || isNaN(day) )
{
alert("Please enter only numbers for the date");
return;
}
var check = new Date( year, month, day );
if ( check.getMonth() != month )
{
alert("That is not a valid date...try again.");
return;
}


// stupid hack for feb 29th:
// but not taking into account time of birth:
if ( month == 1 && day == 29 ) { day = 28; }

// start calculation
var bias = -89; // adjust as needed

// years added to base date
var daynum = bias;
daynum += ( ( year - 1500 ) * 365 );

// months ditto
daynum += monthDays[ month ];

// and then the date
daynum += day;

// then get that number mod 260:
var mod260 = daynum % 260;

// and then the actual sign/page comes from that mod 20:
var mod20 = mod260 % 20;
var offset = Math.floor( mod260 / 20 ) + 1
var choice = pendant[mod20];
var page = base + choice[2];

alert("Number is " + ( mod260 +1 )
+ "\nPendant is " + choice[0] + " with an offset of " + offset
+ "\nGoing to page " + page );
}
</script>
</head>
<body>
<form>
MM / DD / YYYY<br/>
<input name="month" size="1">/<input name="day" size="1">/<input name="year" size="3">
<br/>
<input type="button" value="test" onclick="calculate(this.form);">
</form>
</body>
</html>

xelawho
09-23-2011, 02:46 AM
I just think it's a good thing you're not working with the other calendar the Maya used, the Haab - that one had 18 months of 20 days plus an omen-filled 5 day period called the uayeb.

which I presume would make it 5 days that people were not allowed to have been born on. :eek:

Old Pedant
09-23-2011, 03:24 AM
LOL! Would be just my luck to be a Uayeb babie!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum