By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,835 Members | 1,959 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,835 IT Pros & Developers. It's quick & easy.

credit card validation routine

P: n/a

A friend of mine has a problem with his credit card validation routine
and it is probably a simple thing to solve but I cannot find it.
It has to do with the expiry dates.
What happens is that as each month passes, that month is then not
recognised as being valid, even though the year makes it still valid.
i.e. the number of the month entered has to be bigger than the number
of the current month. Therefor, if it is in august now 09/2005 wil be
valid but
08/2005 will be rejected.
Below quoted is the code, could anybody make sense of this problem?
Thanks!

<HTML>
<HEAD><TITLE>Secure Credit Card Transaction</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFF00">
<script language="JAVASCRIPT">
<!--
//This function validates entry credit card
information
function _vet(){
var thisyear;
var thismonth;
var thisdate;
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].value;
var failed = false;
// check if credit card name has been entered
if (failed == false)
{
if (CCname == "")
{
alert("Please enter name on card");
failed = true;
}
}

// check if credit card number has been entered

if (failed == false)
{
if (CCval == "")

{
alert ("Please enter credit card number");
failed = true;
}
}

// check if credit card type has been entered

if (failed == false)
{
if (CCtype == " ")
{
alert("Please select credit card type");
failed = true;
}
}

//Check if card expiry month has been entered

if (failed == false)
{
if (CCmonth == "Mn")
{
alert("Please enter credit card expiry month");
failed = true;
}
}

//Check if card expiry year has been entered

if (failed == false)
{
if (CCyear == "Yr")
{
alert("Please enter credit card expiry year");
failed = true;
}
}

CCval = _strip_spaces(CCval);

// check if credit card number is actually a number
if (_isinteger(CCval) == false)
{
alert("Credit Card number must be a numeric value only
with or without spaces in between the groups of numbers");
failed = true;
}
if (failed == false)
{
// check for 4242 4242 4242 4242

if (CCval == "4242424242424242")
{
alert ("The credit card number you supplied is
incorrect");
failed = true;
}
}

if (failed == false)
{
}
if (failed == false)
{
//check that the credit card number is valid
if (CC_Validate(CCval) == true)
{

//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <=
thisyear))
{
alert("Your credit card has expired");
failed = true;
}
}
else
{ alert("The credit card number you supplied is
incorrect");
failed = true;
}
if (failed == false)
document.Final.submit();
}
}

function _strip_spaces(_ipstr)
{
var _opstr = '';
var i;
for (i = 1; i <= _ipstr.length; i++)
{
if(_ipstr.substring(i-1, i) != ' ')
_opstr = _opstr + _ipstr.substring(i-1, i);
}
return _opstr;
}

function _isinteger(test_string){
var i;
var non_nums = 0;
for (i = 1; i < test_string.length; i++){
if ((test_string.substring(i-1,i) < '0') ||
(test_string.substring(i-1,i) > '9'))
non_nums++;
}

if (non_nums == 0)
return true;
else
return false;
}

function CC_Validate(ccnumber){
var checksum = 0;
var i;
var digit;
var temp;

var cclength=ccnumber.length;
if (cclength % 2 != 0)
{
cclength += 1;
ccnumber = "0" + ccnumber;
}

for (i = 0; i < cclength; i++){
digit = parseInt(ccnumber.charAt(i));
if ((i % 2) == 0){
digit *= 2;
if (digit > 9)
digit = parseInt(digit / 10) + parseInt(digit
% 10);
}
checksum += digit;
}
if (checksum % 10 == 0)
return true;
else
return false;
}

//-->
</script>

<FORM METHOD = "POST" ACTION = "process.cfm" NAME = "Final">
<INPUT TYPE = "HIDDEN" NAME = "MEMBERSHIP"
VALUE = " ">
<INPUT TYPE = "HIDDEN" NAME =
"APPLICATION_TYPE" VALUE = " ">
<INPUT TYPE = "HIDDEN" NAME = "TITLE1" VALUE
= " ">
<INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME1"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "LAST_NAME1"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "TITLE2" VALUE
= " ">
<INPUT TYPE = "HIDDEN" NAME = "FIRST_NAME2"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "LAST_NAME2"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "STREET" VALUE
= "">
<INPUT TYPE = "HIDDEN" NAME = "TOWN" VALUE =
"">
<INPUT TYPE = "HIDDEN" NAME = "REGION" VALUE
= "">
<INPUT TYPE = "HIDDEN" NAME = "POST_CODE"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "COUNTRY" VALUE
= "">
<INPUT TYPE = "HIDDEN" NAME = "TELEPHONE_NO"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "FAX_NO" VALUE
= "">
<INPUT TYPE = "HIDDEN" NAME = "EMAIL_ADDRESS"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "COMMENTS"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "WHERE_FROM"
VALUE = "">
<INPUT TYPE = "HIDDEN" NAME = "OTHER" VALUE =
"">

<INPUT TYPE="HIDDEN" NAME="SS_TO" VALUE="ma**@address.com">
<INPUT TYPE="HIDDEN" NAME="SS_SUBJECT" VALUE="Membership Credit Card
Secure Order">
<INPUT TYPE="HIDDEN" NAME="SS_NEXTPAGE"
VALUE="http://website/thanks.html">

<CENTER><FONT FACE="Comic Sans MS" SIZE="+2"
COLOR="#FF0000"><B><I>Your Credit Card Details</I></B></FONT></CENTER>
<BR>
<FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Please enter your
Credit Card details below. To avoid any unnecessary delays to your
order, please verify that all your card details are correct before
clicking the "Make Payment" button. Thank you.</FONT>
<HR WIDTH="100%" ALIGN="Center" SIZE="2">

<table>
<tr>
<td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Name On Card
:</font></td>
<td><input name="CardHolder" size=50 maxlength=50></td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr>
<td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Card Number
:</font></td>
<td><input name="CCNo" size="25"></font></td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr>
<td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Card Type
:</font></td>
<td><select name="CreditCard">
<option value=" ">
<option>VISA
<option>Mastercard
</select></td>
</tr>
<tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<td><FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Expiry Date
:</font></td>
<td>
<FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Month</font>
<SELECT NAME = "ExpMonth">
<OPTION VALUE = "Mn">Mn</OPTION>
<OPTION VALUE = "01">01</OPTION>
<OPTION VALUE = "02">02</OPTION>
<OPTION VALUE = "03">03</OPTION>
<OPTION VALUE = "04">04</OPTION>
<OPTION VALUE = "05">05</OPTION>
<OPTION VALUE = "06">06</OPTION>
<OPTION VALUE = "07">07</OPTION>
<OPTION VALUE = "08">08</OPTION>
<OPTION VALUE = "09">09</OPTION>
<OPTION VALUE = "10">10</OPTION>
<OPTION VALUE = "11">11</OPTION>
<OPTION VALUE = "12">12</OPTION>
</SELECT>
<FONT FACE="Comic Sans MS" SIZE="+1" COLOR="#0000FF">Year</font>
<SELECT NAME = "ExpYear">
<OPTION VALUE = "Yr">Yr</OPTION>
<OPTION value = "1998">1998</OPTION>
<OPTION value = "1999">1999</OPTION>
<OPTION value = "2000">2000</OPTION>
<OPTION value = "2001">2001</OPTION>
<OPTION value = "2002">2002</OPTION>
<OPTION value = "2003">2003</OPTION>
<OPTION value = "2004">2004</OPTION>
<OPTION value = "2005">2005</OPTION>
<OPTION value = "2006">2006</OPTION>
<OPTION value = "2007">2007</OPTION>
<OPTION value = "2008">2008</OPTION>
<OPTION value = "2009">2009</OPTION>
<OPTION value = "2010">2010</OPTION>
</SELECT>
</td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr>
<td></td>
<td><INPUT TYPE = "Button" VALUE = " Make Payment" OnClick =
"_vet()"></td>
</tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr>
<td></td>
<td align=left><INPUT TYPE = "Reset"></td>
</tr>
</table>
</FORM>
<BR>
<BR>
</HTML>

Jul 23 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
dries wrote:
A friend of mine has a problem with his credit card validation routine
and it is probably a simple thing to solve but I cannot find it.
It has to do with the expiry dates.
What happens is that as each month passes, that month is then not
recognised as being valid, even though the year makes it still valid.
i.e. the number of the month entered has to be bigger than the number
of the current month. Therefor, if it is in august now 09/2005 wil be
valid but
08/2005 will be rejected.
Below quoted is the code, could anybody make sense of this problem?
Thanks!
//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <=
thisyear))


thisdate = new Date();
thisdate.setMonth(thisdate.getMonth()+1)
thisyear = thisdate.getFullYear()
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <= thisyear))

I'm not sure about the statement above, but it looks wrong.

Mick
Jul 23 '05 #2

P: n/a
Mick White wrote:

if ((CCmonth <= thismonth) && (CCyear <= thisyear))

I'm not sure about the statement above, but it looks wrong.

You are correct, it is wrong. It should be:
if (((CCyear == thisyear) && (CCmonth < thismonth)) ||
((CCyear < thisyear)))
// Expired card. Scissor time.

--
jmm dash list (at) sohnen-moe (dot) com
(Remove .AXSPAMGN for email)
Jul 23 '05 #3

P: n/a
JRS: In article <6l********************************@4ax.com>, dated
Fri, 13 Aug 2004 15:48:35, seen in news:comp.lang.javascript, dries
<dr***@driesbessels.removebeforeuse.com> posted :

A friend of mine has a problem with his credit card validation routine
and it is probably a simple thing to solve but I cannot find it.
Your friend is not competent enough to be entrusted with financial
software.
It has to do with the expiry dates.
What happens is that as each month passes, that month is then not
recognised as being valid, even though the year makes it still valid.
i.e. the number of the month entered has to be bigger than the number
of the current month. Therefor, if it is in august now 09/2005 wil be
valid but
08/2005 will be rejected.
I think you mean that it apparently expires one month early.

<script language="JAVASCRIPT">
Deprecated.
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].value
;
Those are strings. Use ... = + ... to get Numbers.
var failed = false;
// check if credit card name has been entered
if (failed == false)
Should be if (!failed) // throughout.

//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
Gives wrong answer on some systems, AIUI. See via FAQ & sig.
thismonth = thisdate.getMonth();
Gives 0..11 - this the problem that you have seen. Add 1.

if ((CCmonth <= thismonth) && (CCyear <=
thisyear))
Flawed logic. The simplest fix is to use something like
if ( CCyear*12 + CCmonth < thisyear*12 + thismonth) // <= ??

function _isinteger(test_string){
var i;
var non_nums = 0;
for (i = 1; i < test_string.length; i++){
if ((test_string.substring(i-1,i) < '0') ||
(test_string.substring(i-1,i) > '9'))
non_nums++;
}
if (non_nums == 0)
return true;
else
return false;
return non_nums == 0 // is simpler.
}
But one can test for all-digit, or whatever, much more easily with a
RegExp, like

function isI(S) { return /^\d+$/.test(S) }
and with \d{m,n} one can bound the length too.

See <URL:http://www.merlyn.demon.co.uk/js-valid.htm>.

function CC_Validate(ccnumber){
var checksum = 0;
var i;
var digit;
var temp;
Unless you are paid for code by the yard, or in your case metre, there's
no need to have 4 separate vars. Long code is harder to read.

var cclength=ccnumber.length;
if (cclength % 2 != 0)
{
cclength += 1;
ccnumber = "0" + ccnumber;
}

for (i = 0; i < cclength; i++){
digit = parseInt(ccnumber.charAt(i));
if ((i % 2) == 0){
digit *= 2;
if (digit > 9)
digit = parseInt(digit / 10) + parseInt(digit
% 10);
}
checksum += digit;
}


AIUI, parseInt is slow in comparison with unary +.

parseInt(digit/10) *must* AFAICS give 1.
digit%10 does not need parseInt.

I think that d *= 2 ; if (d>9) d-=9 // is sufficient.
// or if ((d*=2)>9) d-=9
Compare, though, with an approach based on
d = [0,2,4,6,8,1,3,5,7,9][d]

It **might** be better to use ccnumber.split('') - OTOH, it might not.

BYW, code that is posted to News should not be subject to machine line-
wrap. It is more efficient for one author to deal with that than for
several readers. Better to use smaller indent units.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #4

P: n/a
Thanks for all the comments, I will relay them to the writer!
Brgds
Dries

Jul 23 '05 #5

P: n/a
Thanks for all the comments, I will relay them to the writer!
Brgds
Dries

Jul 23 '05 #6

P: n/a
On Fri, 13 Aug 2004 15:48:35 +0200, dries
<dr***@driesbessels.removebeforeuse.com> wrote:

[snip]

Before I start, I'd like to note that this page is an anacronism,
containing code and practices that should have been abandoned long ago.
I'd look into CSS and Strict HTML, and catch up with modern web
development. Also validate your pages: <URL:http://validator.w3.org/>.

Finally, when posting code, please don't use tabs. They're inappropriate
for a medium where a line length limit is in force. Use 2 or 4 spaces for
each indentation level.
<HTML>
Valid HTML documents should contain a document type declaration. See
<URL:http://www.w3.org/TR/html401/struct/global.html#h-7.2>.
<HEAD><TITLE>Secure Credit Card Transaction</TITLE>
JavaScript should be considered an optional element on the Web, and it's
presence should not be relied upon when it comes to validation. Moreover,
the execution JavaScript code can be intentionally ignored or manipulated
in order to falsify results.

It also appears that the data submitted by this document might be e-mailed
for further processing. The fact that the transmission to server doesn't
appear to take place through a secure connection, and that the data is
subsequently e-mailed means that you cannot hope to describe the process
as "secure". If this analysis is correct, I would suggest that you cease
lying to your visitors.
</HEAD>
<BODY BGCOLOR="#FFFF00">
<script language="JAVASCRIPT">
The language attribute is deprecated. Furthermore, the required type
attribute makes it redundant. Change this to:

<script type="text/javascript">
<!--
The practice of script hiding is now obsolete. All browsers in use
understand what a SCRIPT element is, even if they cannot execute scripts.
Remove the SGML comment delimiter here, and the closing one, later.
//This function validates entry credit card
information
function _vet(){
var thisyear;
var thismonth;
var thisdate;
var CCname = document.Final.CardHolder.value;
var CCmonth =
document.Final.ExpMonth.options[document.Final.ExpMonth.selectedIndex].value;
var CCyear =
document.Final.ExpYear.options[document.Final.ExpYear.selectedIndex].value;
var CCval = document.Final.CCNo.value;
var CCtype =
document.Final.CreditCard.options[document.Final.CreditCard.selectedIndex].value;
It would be simpler if you first obtained a reference to the form and
referenced the controls from that:

var e = document.forms['Final'].elements,
CCname = e['CardHolder'].value,
CCmonth = e['ExpMonth'].options[e['ExpMonth'].selectedIndex].value,
// etc...
var failed = false;
// check if credit card name has been entered
if (failed == false)
if(!failed) // if not failed

[snip]
//now check that the date is valid i.e. greater or equal to now
thisdate = new Date();
thisyear = thisdate.getYear() + 1900;
Date.getFullYear() returns a four-digit year between 1000 and 9999

thisyear = thisdate.getFullYear();
thismonth = thisdate.getMonth();
if ((CCmonth <= thismonth) && (CCyear <=
Here you're comparing a string, in CCmonth, to a number, in thismonth.
What's more, the number returned by Date.getMonth() is zero-based, not
one-based. Even worse is that that comparison will be true for a valid
date, not an invalid one as intended.

[snip]
if (failed == false)
document.Final.submit();
Validation scripts should not need to call the submit() method. This makes
the page needlessly dependant upon JavaScript. Instead, you should use a
submit button and call the script from the FORM element's submit handler,
returning false if validation failed.

<script type="text/javascript">
function validate(form) {
// test form
return passed; // Return true if passed, false if failed
}
</script>
<!-- Rest of page -->
<form ... onsubmit="return validate(this)">
<!-- Rest of form -->
<input type="submit" value="Submit">
</form>
function _strip_spaces(_ipstr)
[snip]

This would be better done with a simple regular expression:

return _ipstr.replace(/\s+/g, '');

This strips all whitespace. If you want it restricted to only space
characters, replace "\s" with "\x20".
function _isinteger(test_string){
[snip]

Again, a regular expression would be better:

return /^([1-9]|0)[0-9]*$/.test(test_string);

That ensures that the string contains an integer that cannot have leading
zeros. To allow any string, as long as it only contains characters 0-9,
the statement becomes:

return /^[0-9]+$/.test(test_string);
if (non_nums == 0)
return true;
else
return false;
return (non_nums == 0);
}

function CC_Validate(ccnumber){
var checksum = 0;
var i;
var digit;
var temp;

var cclength=ccnumber.length;
if (cclength % 2 != 0)
{
cclength += 1;
ccnumber = "0" + ccnumber;
}

for (i = 0; i < cclength; i++){
digit = parseInt(ccnumber.charAt(i));
If the string has already been validated as containing numbers only, it
would be more efficient to use:

digit = +ccnumber.charAt(i);

In any case, you shouldn't call parseInt() with only a single arguement;
always specify the base.
if ((i % 2) == 0){
digit *= 2;
if (digit > 9)
digit = parseInt(digit / 10) + parseInt(digit
% 10);
Now that digit contains a number, what do you expect parseInt() to do?

digit = (digit / 10) + (digit % 10);

It should also be noted that arithmetic is not exact in JavaScript, and
these operations should be rounded.
}
checksum += digit;
}

if (checksum % 10 == 0)
return true;
else
return false;
}
return !(checksum % 10);

[snip]
<INPUT TYPE="HIDDEN" NAME="SS_TO" VALUE="ma**@address.com">
Any form mail script that asks for the "To" address should be treated with
suspision. They are often attributed to spam complaints. They also expose
a valid e-mail address needlessly. I'd find another one.

[snip]
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
This is invalid HTML. Table rows are required to contain at least one
table cell (TD) or header (TH).

[snip]
<SELECT NAME = "ExpYear">
<OPTION VALUE = "Yr">Yr</OPTION>
<OPTION value = "1998">1998</OPTION>
<OPTION value = "1999">1999</OPTION>
<OPTION value = "2000">2000</OPTION>
<OPTION value = "2001">2001</OPTION>
<OPTION value = "2002">2002</OPTION>
<OPTION value = "2003">2003</OPTION>
What exactly is the point in specifying the years above? If used, they
will always evaluate to false.

[snip]
<td><INPUT TYPE = "Button" VALUE = " Make Payment" OnClick =
"_vet()"></td>


I already stated why this was a bad idea.

[snip]

To demonstrate the various things I've mentioned here, I've produced a
page that replicates the original. You can view it at
<URL:http://www.mlwinter.pwp.blueyonder.co.uk/clj/dries/card.html>. The
presentation could do with some work, but I don't pretend to be a graphic
designer. :)

Good luck,
Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail
Jul 23 '05 #7

P: n/a
JRS: In article <opscqgitemx13kvk@atlantis>, dated Sat, 14 Aug 2004
17:35:15, seen in news:comp.lang.javascript, Michael Winter <M.Winter@bl
ueyonder.co.invalid> posted :
On Fri, 13 Aug 2004 15:48:35 +0200, dries
<dr***@driesbessels.removebeforeuse.com> wrote: Date.getFullYear() returns a four-digit year between 1000 and 9999
That is so. OTOH it may be misleading (are you thinking of VBscript,
though the lower limit there is 100?); I believe the range to be
-271821-04-21 to +275760-09-13; 10^8 days from the start of 1970 GMT.

Most browsers in current use should have getFullYear.

In any case, you shouldn't call parseInt() with only a single arguement;
always specify the base.
In this case, IIRC, the first argument is a single digit string; 1..9
will be taken as decimal, and 0 as octal, AIUI. Granted, parseInt is
not needed. It would probably be faster to use charCodeAt and subtract
48.

It should also be noted that arithmetic is not exact in JavaScript, and
these operations should be rounded.


Integer arithmetic is exact when all values remain in the range +-2^53
inclusive and numbers are divided (/) only by factors. That is the case
here.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #8

P: n/a
On Sun, 15 Aug 2004 13:29:11 +0100, Dr John Stockton
<sp**@merlyn.demon.co.uk> wrote:

[range of Date.getFullYear()]
That is so. OTOH it may be misleading (are you thinking ofVBscript,
though the lower limit there is 100?);
No. I took that from the JavaScript reference as it was hand at the time.
I believe the range to be -271821-04-21 to +275760-09-13; 10^8 daysfrom
the start of 1970 GMT.
I calculated a different value, but Opera returns the values you state
above. In any event, its of that order of magnitude.
Most browsers in current use should have getFullYear.
It was added to JavaScript in v1.3. I wish the ECMAScript specification
noted what was added, when.

[parseInt()]
In this case, IIRC, the first argument is a single digit string; 1..9
will be taken as decimal, and 0 as octal, AIUI.
That's what's frequently stated, but it appears to be incorrect.

According to ECMA-262, the absence of a second argument, or 0, defaults to
base-10. If no explicit radix was specified, an implementation must switch
if the length of the string "is at least 2 and the first two
characters...are either '0x' or '0X'" where it defaults to base-16. If the
length of the string "is at least 1 and the first character...is '0'", it
is up to the implementation to decide whether to switch to base-8 or use
the current base.

Granted, most implementations will change to base-8, but there is no
guarantee.

Note that this does not apply to other methods of conversion, such as
unary plus or Number(). In those cases, a "decimal may have any number of
leading 0 digits".
Granted, parseInt is not needed. It would probably be faster to use
charCodeAt and subtract 48.


Possibly. I think I'd go for clarity, though.

[snip]

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail
Jul 23 '05 #9

P: n/a
JRS: In article <opscsda1y0x13kvk@atlantis>, dated Sun, 15 Aug 2004
18:20:35, seen in news:comp.lang.javascript, Michael Winter <M.Winter@bl
ueyonder.co.invalid> posted :

[parseInt()]
In this case, IIRC, the first argument is a single digit string; 1..9
will be taken as decimal, and 0 as octal, AIUI.


That's what's frequently stated, but it appears to be incorrect.

According to ECMA-262, the absence of a second argument, or 0, defaults to
base-10. If no explicit radix was specified, an implementation must switch
if the length of the string "is at least 2 and the first two
characters...are either '0x' or '0X'" where it defaults to base-16. If the
length of the string "is at least 1 and the first character...is '0'", it
is up to the implementation to decide whether to switch to base-8 or use
the current base.

If the only character is '0', it seems silly to interpret it as a
special case in decimal, since the octal interpretation gives the same
answer.

IMHO, ECMA 263 3rd Edn 15.1.2.2, list item 12 allows the radix to be 8
or unchanged in this case.

Systems interpreting 077 as seventy-seven rather than as sixty-three
will no doubt interpret '0' as decimal, though.

ECMA evidently does not like leading-zero-means-octal, but cannot
disregard precedent.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #10

P: n/a
On Mon, 16 Aug 2004 11:56:15 +0100, Dr John Stockton
<sp**@merlyn.demon.co.uk> wrote:
JRS: In article <opscsda1y0x13kvk@atlantis>, dated Sun, 15 Aug 2004
18:20:35, seen in news:comp.lang.javascript, Michael Winter
<M.******@blueyonder.co.invalid> posted :
[snip]
According to ECMA-262, the absence of a second argument, or 0, defaults
to base-10.


Just to clarify that sentence, I meant to say that an unspecified or zero
(0) value for the second argument defaults to base-10.

[snip]
If the only character is '0', it seems silly to interpret it as a
special case in decimal, since the octal interpretation gives the same
answer.
If the radix was explicitly specified as 10, no radix switch will occur,
no matter what the format of the string. This is true for all explicitly
set, valid values for radix. A switch to octal or hexadecimal may only
occur if no radix was specified (or specified as zero), and even then,
octal is optional.[1]

[snip]
ECMA evidently does not like leading-zero-means-octal, but cannot
disregard precedent.


I think that the one and only time I was forced to use octal was when I
programmed a Z80 and the mnemonics were listed with octal instruction
codes, but they needed to be input in hexadecimal (or vice versa, I
forget). However, I couldn't begin to guess at the number of times I've
used leading-zero decimal or hexadecimal.

It's no great loss that automatic octal interpretation is no longer
required in an implemention - a number with a single leading zero can
easily be tested with a regular expression and, if found, parseInt can be
called with an explicit 8.

That said, perhaps it would probably be better to state catagorically yes
or no, rather than, "it's up to you".

Mike

[1] I'm sure that you knew that, but your statement seemed ambiguous, so I
wanted to be sure, especially in the light of my own (now rewritten)
confused sentence.

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail
Jul 23 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.