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

sorting dates

P: n/a
If I had a date in the format "01-Jan-05" it does not sort properly
with my sort routine:

function compareDate(a,b)
{
var date_a = new Date(a);
var date_b = new Date(b);
if (date_a < date_b)
{ return -1; }
else
{
if (date_a > date_b)
{ return 1; }
else
{ return 0; }
}
}

I guess it expects the date in mm/dd/yyyy format.

Do I have to change:

var date_a = new Date(a);
var date_b = new Date(b);

so it recognizes a correct format?

Mike

Jul 28 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
mike wrote:
If I had a date in the format "01-Jan-05" it does not sort properly
with my sort routine:
The arguments for Date() are:

Date( [year[, month[, date[, hours[, minutes[, seconds[, ms]]]]]]])

All arguments are optional.

function compareDate(a,b)
{
var date_a = new Date(a);
Assuming input is as posted and noting that months are numbered from 0
to 11:

var months = {'jan':0, 'feb':1, 'mar':2, 'apr':3, 'may':4, 'jun':5,
'jul':6, 'aug':7, 'sep':8, 'oct':9, 'nov':10, 'dec':11 };
var aBits = a.split('-');
var date_a = new Date( a[2], months[a[1].toLowerCase()], a[0] );

and the same for b. Note that you should validate all input first and
that 'date_a' is a valid date for whatever purpose you intend to use it for.

e.g. if '00-Jul-2005' is input, the resulting date will be 30-Jun-2005.
'32-Jul-2005' gives 01-Aug-2005
var date_b = new Date(b);
if (date_a < date_b)
{ return -1; }
else
{
if (date_a > date_b)
{ return 1; }
else
{ return 0; }
}
}

I guess it expects the date in mm/dd/yyyy format.


No, 'it' doesn't. There is a lot more stuff on dates here:

<URL:http://www.merlyn.demon.co.uk/js-dates.htm>
[...]

--
Rob
Jul 29 '05 #2

P: n/a
Rob thanks i can understand what is goin on there.

works fine.

Jul 29 '05 #3

P: n/a
RobG wrote:
mike wrote:
If I had a date in the format "01-Jan-05" it does not sort properly
with my sort routine:
As a hint, simply reformatting as yyyy-mm-dd will sort correctly (and be
in an ISO acceptable format that is recognised internationally). There
is no need for using date objects at all (though you may wish to use
them to validate your dates before attempting to sort them).

Below is a simple example, no validation of input or dates is attempted
but would be required in practice.

I have kept the months as zero-indexed - you may wish to change that.
<script type="text/javascript">

var months = { 'jan':0, 'feb':1, 'mar':2, 'apr':3,
'may':4, 'jun':5, 'jul':6, 'aug':7,
'sep':8, 'oct':9, 'nov':10, 'dec':11 };

function sortDates(){
var D = [];
var i = arguments.length;
while ( i-- ) {
D[i] = formatAsYMD( arguments[i] );
}
return D.sort();
}

function formatAsYMD( str ) {
var x = str.split('-');
return x[2] + '-'
+ addZ( months[x[1].toLowerCase()] ) + '-'
+ addZ( x[0] );
}

function addZ( x ) {
return ( x < 10 )? '0' + x : x;
}

</script>

<form action="">
<input name="dStrA" value="28-Jul-2005">
<input name="dStrB" value="28-Aug-2005">
<input name="dStrC" value="2-Feb-2003">
<input type="button" value="show date" onclick="
alert( sortDates(
this.form.dStrA.value,
this.form.dStrB.value,
this.form.dStrC.value
)
);
">

</form>


The arguments for Date() are:

Date( [year[, month[, date[, hours[, minutes[, seconds[, ms]]]]]]])

All arguments are optional.

function compareDate(a,b)
{
var date_a = new Date(a);

Assuming input is as posted and noting that months are numbered from 0
to 11:

var months = {'jan':0, 'feb':1, 'mar':2, 'apr':3, 'may':4, 'jun':5,
'jul':6, 'aug':7, 'sep':8, 'oct':9, 'nov':10, 'dec':11 };
var aBits = a.split('-');
var date_a = new Date( a[2], months[a[1].toLowerCase()], a[0] );

and the same for b. Note that you should validate all input first and
that 'date_a' is a valid date for whatever purpose you intend to use it
for.

e.g. if '00-Jul-2005' is input, the resulting date will be 30-Jun-2005.
'32-Jul-2005' gives 01-Aug-2005
var date_b = new Date(b);
if (date_a < date_b)
{ return -1; }
else
{
if (date_a > date_b)
{ return 1; }
else
{ return 0; }
}
}


And that could be:

return ( a < b );

I guess it expects the date in mm/dd/yyyy format.

No, 'it' doesn't. There is a lot more stuff on dates here:

<URL:http://www.merlyn.demon.co.uk/js-dates.htm>
[...]

--
Rob
Jul 29 '05 #4

P: n/a
Ron,

i am pulling the dates from Oracle and they are in that 27-Jul-05
format. I'd like to change them by using some oracle functions or
coldfusion functions but am unable to (this would be another subject
alltogether) until it gets to the page. The data is loaded to the page
in an array is loaded dynamically. The user has the choice of sorting
the columns, thus the array needs to be sorted and reapplied to the
page.

The page does not know how many fields will be in the array page or
what order they will be. The user selected them on the previous page.

So thanks for your help.I think that will work and I'll going to chek
out this other code as well.

Jul 29 '05 #5

P: n/a
fox


mike wrote:
Ron,

i am pulling the dates from Oracle and they are in that 27-Jul-05
format. I'd like to change them by using some oracle functions or
coldfusion functions but am unable to (this would be another subject
alltogether) until it gets to the page. The data is loaded to the page
in an array is loaded dynamically. The user has the choice of sorting
the columns, thus the array needs to be sorted and reapplied to the
page.

The page does not know how many fields will be in the array page or
what order they will be. The user selected them on the previous page.

So thanks for your help.I think that will work and I'll going to chek
out this other code as well.


// a little conversion shortcut

var mos = { Jan:"01",
Feb:"02",
Mar:"03",
Apr:"04",
May:"05",
Jun:"06",
Jul:"07",
Aug:"08",
Sep:"09",
Oct:"10",
Nov:"11",
Dec:"12"
};

String.prototype.oracleDateValue = function()
{
return this.replace(/(\d+)-(\w+)-(\d+)/,
function(s, p1, p2, p3)
{
return "20" + p3 + mos[p2] + p1;
});
}
function
oracleDateCompare(a,b)
{
return a.oracleDateValue() - b.oracleDateValue();
}
oracleDatesArray.sort(oracleDateCompare);
** I have assumed that oracle uses leading zeros where necessary, ex:

01-Jun-00 for June 1, 2000

if not, you can force leading zeros for dates (and months) with:

("0" + p1).replace(/(\d\d)$/,"$1");
anyway, the oracleDateValue should return an integer in YYYYMMDD format
(year 2000 >) which sorts quite easily.
to answer your previous post:

String.prototype.oracleDate2Common = function()
{

return this.replace(/(\d+)-(\w+)-(\d+)/,
function(s, p1, p2, p3)
{
return mos[p2].replace(/^0/,"") + "/" +
p1.replace(/^0/,"") + "/20" + p3;
});
}

will convert 25-Aug-05 to 8/5/2005

you can simplify the expression by setting up the mos object without
leading zeros.

Jul 29 '05 #6

P: n/a
fox wrote:


mike wrote:
[...] String.prototype.oracleDateValue = function()
{
return this.replace(/(\d+)-(\w+)-(\d+)/,
function(s, p1, p2, p3)
{
return "20" + p3 + mos[p2] + p1;
});


Function arguments in String.replace() are not supported in some
browsers, e.g. Safari and according to Mike Winter:

"... IE5 and earlier ... don't support function arguments, and
Opera 6 won't perform a replacement at all (a no-op)."

There may be others.

Returned strings should probably contain delimiters (say '-') to make
them more obviously dates (yyyy-mm-dd). Sorting should be unaffected.

[...]
--
Rob
Jul 29 '05 #7

P: n/a
fox


RobG wrote:
fox wrote:


mike wrote:
[...]
String.prototype.oracleDateValue = function()
{
return this.replace(/(\d+)-(\w+)-(\d+)/,
function(s, p1, p2, p3)
{
return "20" + p3 + mos[p2] + p1;
});

Function arguments in String.replace() are not supported in some
browsers, e.g. Safari and according to Mike Winter:

"... IE5 and earlier ... don't support function arguments, and
Opera 6 won't perform a replacement at all (a no-op)."



There may be others.
That is a PISS POOR argument. From whom are you repeating it?
[my take on these other browsers]
Until these browsers get their numbers up... they don't matter -- not to
my clients, and therefore, not to me.

My clients are business people... they want sites for other business
people... they're ALL using PCs with some form of Windows and using IE
as their browser. In the past 2 years, I've talked with exactly 1
"prospective" client that used Firefox (so NOT a problem for me!). It
would seem the only people around here (i.e., in the area where I live)
using "off-brand" browsers are the programmers -- and that "prospective"
client just picked my brain a little, then did the work himself.
So, 100% of my clients use IE5.5+ -- when I ask about Netscape or "other
browser" support -- oddly enough -- THEY don't care (I do a LOT of work
I don't have to do -- but I DO draw a line)... Everybody THEY know uses IE.

Safari has so many other problems with it -- I only use it to read my
daily news... any serious surfing on the Mac and I go to Firefox.

Opera SUCKED so badly early on -- i gave up after the v3 (i think) --
and it's numbers are still so low... they're just one of the arguments
for those who keep saying "you can't do something because..." Besides --
don't you have to pay for opera? It will never be a contender.

[back to topic]
And what exactly is keeping these browsers from supporting this feature?
Even *I* can write the code that handles functions in replace:

String.prototype.replace2 = function()
{

if(arguments.length < 2) return null; // or whatever...

var re = arguments[0];
var replacement = arguments[1];

var matches = this.match(re);

if(typeof replacement == "function")
{
return replacement( matches[0],
matches[1],
matches[2],
matches[3],
matches[4],
matches[5],
matches[6],
matches[7],
matches[8],
matches[9]);
}
else
{
return "I'll leave the rest as an exercise!";
// $1..$9 must be accounted for...
// hence, (hint) the matches array from 0 to 9
}
}
and then (even with just this little bit) my little date "turnarounds"
WILL work in Safari [tested] (as well as IE, and Mozilla(s)); [I won't
even install Opera anymore so -- no tellin'... I will assume Konqueror
has similar problems as Safari is based on it]
Finally -- Just because something doesn't work in all browsers, doesn't
mean that with a little effort, it can't be made to work. I'm tired of
all the laziness of those who sit back and criticize or complain that
something cannot be used because some pitiful relatively insignificant
browser doesn't support the feature when worthwhile solutions to
problems can be found. This one was easy (it took considerably longer to
write this response than it did to come up with the solution - about 8
minutes). I don't let a little thing like "minor browser" disfunction
stand in my way. Why do you? Because somebody *else* said so?


Returned strings should probably contain delimiters (say '-') to make
them more obviously dates (yyyy-mm-dd). Sorting should be unaffected.

comparing strings no doubt takes longer than comparing numbers.

if all dates to be sorted are in YYYY-MM-DD format, and -- worst case,
they are all in the first week of the same year and month, then the
MINIMUM # of comparisons needed to be made to pass one as <> the other
would be 10 (one per character as long as they are equal) - two week
span, 9 -- etc... Unless, of course, JavaScript can compare "chunks" of
strings in one "throw" (I used to do it in C -- up to 8 characters at a
time -- typecast to longints -- really good way to speed up searches too)
with integers:
2 numbers, 1 subtraction... you do the math...

[but this only matters if the operations are "time-critical"]

oh... that little YYYYMMDD integer format -- it's called a "packed" date
format (packing integers is a "time-honored programming tradition") --
been around for considerably longer than JavaScript. Technically, the
"digits" should be hexadecimal, but for sorting purposes, decimal digits
work just as well with the extra added benefit of being easily readable
in human terms.
[...]




Jul 29 '05 #8

P: n/a
fox wrote:
[...]
Function arguments in String.replace() are not supported in some
browsers, e.g. Safari and according to Mike Winter:

"... IE5 and earlier ... don't support function arguments, and
Opera 6 won't perform a replacement at all (a no-op)."

There may be others.

That is a PISS POOR argument. From whom are you repeating it?


The attribution is right where I posted it. It came from another
thread where you also proposed using functions with the replace
method. It is useful to point out to others where things may fail -
what they choose to do with that advice is completely up to them.
[my take on these other browsers]
Until these browsers get their numbers up... they don't matter -- not to
my clients, and therefore, not to me.
Whatever is posted here is expected to be suitable for the web in
general and not be specific to intranets or corporate clients. If
specific advice has know limitations then they should be noted so that
others may decide for themselves whether it suits their circumstance
or not.

Excluding certain browsers purely on the basis that they are a small
minority is not reasonable.

[...]
Returned strings should probably contain delimiters (say '-') to make
them more obviously dates (yyyy-mm-dd). Sorting should be unaffected.


comparing strings no doubt takes longer than comparing numbers.

if all dates to be sorted are in YYYY-MM-DD format, and -- worst case,
they are all in the first week of the same year and month, then the
MINIMUM # of comparisons needed to be made to pass one as <> the other
would be 10 (one per character as long as they are equal) - two week
span, 9 -- etc... Unless, of course, JavaScript can compare "chunks" of
strings in one "throw" (I used to do it in C -- up to 8 characters at a
time -- typecast to longints -- really good way to speed up searches too)


The idea is to have them in a format that sort() can use without any
further modification and that doesn't require a comparison function.
Whether they are strings or numbers will likely make very little
difference in the OP's case as whatever operations are done to the
table rows will likely take far, far longer than the actual sort.
with integers:
2 numbers, 1 subtraction... you do the math...
Unless you know the actual internal algorithm of how the sort works,
discussing what you think it might be doing means you are basing your
argument on conjecture.

[but this only matters if the operations are "time-critical"]

oh... that little YYYYMMDD integer format -- it's called a "packed" date
format (packing integers is a "time-honored programming tradition") --
been around for considerably longer than JavaScript. Technically, the
"digits" should be hexadecimal, but for sorting purposes, decimal digits
work just as well with the extra added benefit of being easily readable
in human terms.


So you know some other names for that format - bravo. I made no
assertion that it was peculiar to JavaScript - I know it isn't.

I suggested the ISO standard format since it is an international
standard that is unambiguous and widely understood and therefore very
well suited for the web. It also sorts effortlessly and therefore is
likely suitable for this and many other purposes.

The OP may think it's a load of crap and totally ignore everything I
posted - ain't life grand.
--
Rob
Jul 29 '05 #9

P: n/a
As the OP is appreciate the help, but not the bickering much.

My opinion: I really don't have the time to write code for each
browser. It depends on who the user is. I have a neighborhood site
where there are alot of older people and some of them have macs, and
some netscape, but mostly ie. Still i have to write generic code for
them.

I prefer to write for IE, because of the dhtml. I have some pages that
support only ie and i tell the user up front, i.e. they can't login
unless they are using IE. If they dont have IE they can't play.

I really appreciate all the posters help here though, and comments.

Mike

Jul 29 '05 #10

P: n/a
Lee
mike said:
I prefer to write for IE, because of the dhtml.


That hasn't really been a good reason for several years, has it?

Forcing non-technical people to use IE is like the Post Office
requiring that they leave their doors unlocked if they want their
mail delivered.

Jul 29 '05 #11

P: n/a
JRS: In article <11********************@g47g2000cwa.googlegroups.c om>,
dated Thu, 28 Jul 2005 16:48:20, seen in news:comp.lang.javascript, mike
<hi****@charter.net> posted :
If I had a date in the format "01-Jan-05" it does not sort properly
with my sort routine: I guess it expects the date in mm/dd/yyyy format.


So see what new Date() makes of such a string; don't try too much at
once. I get NaN for it.

Don't rely on browsers to recognise mm/dd/yyyy, a.k.a. FFF; it's not
specified, and may depend on localisation. Eschew FFF utterly on the
Internet.

My first post in the thread you started earlier indicated how to read
your date format; the cited Web page shows how to convert it to an ISO
8601 string and/or to a date object; ISO strings sort directly. Date
Objects, IIRC, are by default sorted alphabetically on the result of
..toString() - inefficient and wrong - but you only need
function Compare DateObjects(D1, D2) { return D2-D1 }
IIRC - see my js-dates.htm#SbDT

Read the FAQ; see below.

--
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 29 '05 #12

P: n/a
JRS: In article <dc**********@news.datasync.com>, dated Fri, 29 Jul
2005 03:43:07, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :


comparing strings no doubt takes longer than comparing numbers.
Perhaps so. But the comparison operator should be implemented at the
ASM level or similar; so, for strings of the length in question, ISTM
reasonably likely that the overall time will be dominated by other parts
of the routine. If it matters, it should be tested.

With 8-character strings, using the quickest test loop I know, I find
the loop for comparison of equal 8-character Strings to be about 10%
slower than that for the corresponding Numbers, loop overhead being
about 20%. Other browsers are likely to differ.

if all dates to be sorted are in YYYY-MM-DD format, and -- worst case,
they are all in the first week of the same year and month, then the
MINIMUM # of comparisons needed to be made to pass one as <> the other
would be 10 (one per character as long as they are equal) - two week
span, 9 -- etc... Unless, of course, JavaScript can compare "chunks" of
strings in one "throw" (I used to do it in C -- up to 8 characters at a
time -- typecast to longints -- really good way to speed up searches too)
IIRC, the PC CPU instruction set provides for efficient comparisons of
strings of 8-bit characters, and may do so, intentionally or otherwise,
foe 16-bit ones.

oh... that little YYYYMMDD integer format -- it's called a "packed" date
format (packing integers is a "time-honored programming tradition") --
been around for considerably longer than JavaScript. Technically, the
"digits" should be hexadecimal, but for sorting purposes, decimal digits
work just as well with the extra added benefit of being easily readable
in human terms.


It's not rightly called "packed". When discussing ISO 8601 formats, one
should use ISO 8601 terminology.

The string 'YYYYMMDD' is "Basic format".
The string 'YYYY-MM-DD' is "Extended format".

A Basic format string can (with unary +) be converted to a javascript
Number; but that is an IEEE Double, not an integer. Numbers in
javascript do not have decimal digits.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
Jul 29 '05 #13

P: n/a
fox


RobG wrote:
fox wrote:
[...]
Function arguments in String.replace() are not supported in some
browsers, e.g. Safari and according to Mike Winter:

"... IE5 and earlier ... don't support function arguments, and
Opera 6 won't perform a replacement at all (a no-op)."

There may be others.
That is a PISS POOR argument. From whom are you repeating it?

The attribution is right where I posted it. It came from another thread
where you also proposed using functions with the replace method. It is
useful to point out to others where things may fail - what they choose
to do with that advice is completely up to them.


solutions are better than advice... interesting that you deleted mine
from this post
> [my take on these other browsers]
Until these browsers get their numbers up... they don't matter -- not
to my clients, and therefore, not to me.

Whatever is posted here is expected to be suitable for the web in
general and not be specific to intranets or corporate clients. If
specific advice has know limitations then they should be noted so that
others may decide for themselves whether it suits their circumstance or
not.


So -- it's just about "lightweight solutions for lightweight browsers"
-- right?

Comply or Die worked against Netscape 4. So why not all the others? Now
it's "let's mollycoddle all these poor minority browsers to give them a
chance to survive?" Don't make me laugh.


Excluding certain browsers purely on the basis that they are a small
minority is not reasonable.
It's more than reasonable -- it's called competition... If "minority"
browsers can't pull it together enough to survive... they are doomed to
die out... I am not compelled to hold back anything to accommodate poor
impelementations. If these minority browsers want to survive, they have
to fix their shortcomings... that's all there is to it. Before you take
further issue with this, I am merely reflecting the attitude of all of
those on this and other newsgroups when everybody couldn't wait for
Netscape 4 to "die and go away"... that precedence has been set.
String.replace with function as second argument was implemented in
JavaScript 1.3 -- FULLY six years ago. There is NO excuse. ECMA
describes String.prototype.replace with the first case for the second
argument (replaceValue) as a *function.* There IS no excuse. I am fully
justified to offer string.replace options with functions as second
arguments.

[...]
Returned strings should probably contain delimiters (say '-') to make
them more obviously dates (yyyy-mm-dd). Sorting should be unaffected.

comparing strings no doubt takes longer than comparing numbers.

if all dates to be sorted are in YYYY-MM-DD format, and -- worst case,
they are all in the first week of the same year and month, then the
MINIMUM # of comparisons needed to be made to pass one as <> the other
would be 10 (one per character as long as they are equal) - two week
span, 9 -- etc... Unless, of course, JavaScript can compare "chunks"
of strings in one "throw" (I used to do it in C -- up to 8 characters
at a time -- typecast to longints -- really good way to speed up
searches too)

The idea is to have them in a format that sort() can use without any
further modification and that doesn't require a comparison function.
Whether they are strings or numbers will likely make very little
difference in the OP's case as whatever operations are done to the table
rows will likely take far, far longer than the actual sort.
with integers:
2 numbers, 1 subtraction... you do the math...

Unless you know the actual internal algorithm of how the sort works,
discussing what you think it might be doing means you are basing your
argument on conjecture.

Offhand, I don't for sure -- but I've seen enough of them to guess...
probably quicksort...

I'm basing my argument on the "typical" sorting algorithms I have come
across (as well as written from the ground up) in "my time." I'm also
weighing in the algorithms I have worked out for myself. For strings,
the "typical" algorithm compares one character (code) at a time until
there is a difference, at which point the choice of order is made. For
long strings, this can be a "lengthy" process, all things being
relative. Atypical algorithms will optimize comparisons by measuring
data, then "biting" it off a "register" at a time. 64-bit registers have
been around for some time now, so that means 8 characters at a time.
Eight characters can be typecast to an unsigned long long and compared
numerically. You can't do this from the javascript language itself, that
requires pointers (direct memory addressing) (not to mention long long
datatypes), and I would be surprised if the engine actually takes this
approach.

take for example: reciprocity and reciprocate.

it would take the typical sort algorithm 9 loops to find 'a' vs 'i'. the
atypical algorithm described would take only 2. The atypical routine
"views" the raw data as:

0x7265636970726f63 0x69747900...trash // '00' is end of string \0
and
0x7265636970726f63 0x61746500...trash

for case-insensitve, you can bitwise | 0x2020202020202020
if "last word" is not exactly 8 bytes long, the extra bytes should be
zeroed/cleared in case of = entries.

in MORE than 75% of the time, the atypical algorithm will find a
difference on the first comparison.

[AFAIK I am the inventor of this comparison algorithm... approx. 10 or
so years ago when 64-bit integer support became available on Macs...now
that doesn't mean that others might have developed the same or similar
on *their* own and I wouldn't believe it if I were the ONLY one to come
up with this -- but I doubt it is in use in the JS engine -- and upon
"cursory" checking, that appears to be the case]

In C, where one has low-level access to the CPU and direct memory
access, the algorithms in use are easily overridden and/or customized.
Since this access is not available through JavaScript, the algorithms in
place do not really concern me as I am not likely to be writing or
improving any of them...ever. I don't have the time nor the inclination.

I have considerable background and experience on which to base my
conjecture... and most general purpose public domain sort algorithms are
of the "typical" type. Your statement makes it sound like you might
know better -- why didn't you enlighten us as to which kind of algorithm
*is* used?

[but this only matters if the operations are "time-critical"]

oh... that little YYYYMMDD integer format -- it's called a "packed"
date format (packing integers is a "time-honored programming
tradition") -- been around for considerably longer than JavaScript.
Technically, the "digits" should be hexadecimal, but for sorting
purposes, decimal digits work just as well with the extra added
benefit of being easily readable in human terms.

So you know some other names for that format - bravo.


This isn't "special" or even "arcane" knowledge. And "that format" is
not meant for representing information to humans (it's not really ANY
"format" - packing can take any arrangement) -- it is used only in
programming for data storage/manipulation.

Packing data is not language specific -- nor is it specific to dates. It
is, and has been for a very long time, a useful programming "tool." It
is used in data compression algorithms. One application of packed data
you SHOULD know about is RGB or HTML color representation: #CC9933 -- CC
is the red color component, 99 the green color component, and 33 the
blue color component. Using "integers" to store more than one piece of
datum is considered "packing." [packing does not really require integers
-- any block of memory will do -- longints, arrays, etc...even just
simple bytes.]
I made no
assertion that it was peculiar to JavaScript - I know it isn't.

I suggested the ISO standard format since it is an international
standard that is unambiguous and widely understood and therefore very
well suited for the web. It also sorts effortlessly and therefore is
likely suitable for this and many other purposes.
All I'm saying is: if you have a considerable number of dates, all
within a narrow span of time, it is worth the effort to convert to a
number and use subtraction to make the comparison. In terms of
programming, it is usually MORE useful to keep the date in integer
(number) format, and use conversion to string for display instead of
vice versa... Make sense? ISO date format makes going from packed date
to string very easy.
The OP may think it's a load of crap and totally ignore everything I
posted - ain't life grand.
granted...


Jul 30 '05 #14

P: n/a
fox


Dr John Stockton wrote:
JRS: In article <dc**********@news.datasync.com>, dated Fri, 29 Jul
2005 03:43:07, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :

comparing strings no doubt takes longer than comparing numbers.

Perhaps so. But the comparison operator should be implemented at the
ASM level or similar;


Not relevant -- no access to asm level in js.
so, for strings of the length in question, ISTM
reasonably likely that the overall time will be dominated by other parts
of the routine. If it matters, it should be tested.
i doubt it matters much in JS...

With 8-character strings, using the quickest test loop I know, I find
the loop for comparison of equal 8-character Strings to be about 10%
slower than that for the corresponding Numbers, loop overhead being
about 20%. Other browsers are likely to differ.
not relevant... you didn't "get it"... and you "conveniently" cut off "I
used to do it in C"! This can't be done in JS... you wasted your time
"testing" this in JS... at the "engine level" of JS's sort routine is
STILL the character by character comparison (I checked) and whether you
chop the string in sections of 8 or not, you still have string data types.


if all dates to be sorted are in YYYY-MM-DD format, and -- worst case,
they are all in the first week of the same year and month, then the
MINIMUM # of comparisons needed to be made to pass one as <> the other
would be 10 (one per character as long as they are equal) - two week
span, 9 -- etc... Unless, of course, JavaScript can compare "chunks" of
strings in one "throw" (I used to do it in C -- up to 8 characters at a
time -- typecast to longints -- really good way to speed up searches too)

IIRC, the PC CPU instruction set provides for efficient comparisons of
strings of 8-bit characters, and may do so, intentionally or otherwise,
foe 16-bit ones.

yes... registers are loaded in 1 clock -- up to 64 bits on "modern"
machines... so why not 64 bits worth of characters in one instruction?
It's just bits...think of your basic character set as base256 numbers
and each character a digit. (Whether of not there is a human readable
glyph for each value doesn't make any difference to a computer.)
oh... that little YYYYMMDD integer format -- it's called a "packed" date
format (packing integers is a "time-honored programming tradition") --
been around for considerably longer than JavaScript. Technically, the
"digits" should be hexadecimal, but for sorting purposes, decimal digits
work just as well with the extra added benefit of being easily readable
in human terms.

It's not rightly called "packed". When discussing ISO 8601 formats, one
should use ISO 8601 terminology.


I wasn't talking about iso date formats... so... not relevant.

Packed is NOT an ISO term -- it is a programmer's term for loading
multiple data into allocated memory, usually integer types (but chars,
arrays, and others can be used as well) -- data compression, if you will.

RGBColor and/or HTMLColor can also be referred to as packed color data.

The string 'YYYYMMDD' is "Basic format".
The string 'YYYY-MM-DD' is "Extended format".

A Basic format string can (with unary +) be converted to a javascript
Number; but that is an IEEE Double, not an integer.

Number "type" is not relevant (nor is the *value* of the number
relevant: 0x20050730 would still yield the same result [but limited to
the next 5994 years.])

The number is just a scalar which should compare faster than the
strings. Relative magnitude is all that is necessary. The fact that
their "human readable" appearance "coincides" with an ISO date format is
inconsequential but convenient. The number used would be arranged in the
same order whether or not the iso standard existed.

Numbers in
javascript do not have decimal digits.


LOL...

a couple possible responses:

1) What *possible* purpose does this statement serve?!?

and

2) What kind of digits DO Numbers have? fingers? toes? snorks?
D


Jul 31 '05 #15

P: n/a
JRS: In article <dc**********@news.datasync.com>, dated Sat, 30 Jul
2005 20:54:00, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :


Dr John Stockton wrote:
JRS: In article <dc**********@news.datasync.com>, dated Fri, 29 Jul
2005 03:43:07, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :

comparing strings no doubt takes longer than comparing numbers.

Perhaps so. But the comparison operator should be implemented at the
ASM level or similar;


Not relevant -- no access to asm level in js.


ASM level or similar - which includes any efficiently-compiled high
level language - is what should do the work of executing javascript
operations. We have no direct access, agreed.
so, for strings of the length in question, ISTM
reasonably likely that the overall time will be dominated by other parts
of the routine. If it matters, it should be tested.


i doubt it matters much in JS...


If there is doubt whether it matters, it should be tested; I did so.
With 8-character strings, using the quickest test loop I know, I find
the loop for comparison of equal 8-character Strings to be about 10%
slower than that for the corresponding Numbers, loop overhead being
about 20%. Other browsers are likely to differ.


not relevant... you didn't "get it"... and you "conveniently" cut off "I
used to do it in C"! This can't be done in JS... you wasted your time
"testing" this in JS... at the "engine level" of JS's sort routine is
STILL the character by character comparison (I checked) and whether you
chop the string in sections of 8 or not, you still have string data types.


You miss the point. One can convert an 8-character String to Number, if
the string be a string of decimal digit characters. Sort speed of
Strings will not depend on the exact identity of the characters in them;
so one can meaningfully compare the comparison speed of Strings like
"12345678" with that of Numbers like 12345678, each being adequately
representative of the general case.
For sorting a large number of dates, one should address the question of
whether it is worthwhile to convert the dates to/from a more efficiently
sortable form before/after sorting. That conversion takes time o(N)
whereas sorting will be >o(N). Hence it is worth (slightly) converting
from String to Number for a sufficiently large number of dates, if my
result is typical.

In sorting Date Objects, things are a little different; Date Objects
store dates as Number, but a non-default Sort is needed, so here there
is the added overhead of calling (>o(N) times) a simple sort function;
however, the conversions between Date Object and Number are simpler,
involving only administrative processing.
The rest of your response is best ignored.

--
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 31 '05 #16

P: n/a
fox wrote:
[...]

So -- it's just about "lightweight solutions for lightweight browsers"
-- right?

Comply or Die worked against Netscape 4. So why not all the others? Now
it's "let's mollycoddle all these poor minority browsers to give them a
chance to survive?" Don't make me laugh.


That attitude is at once both ignorant and arrogant.

Your notion that Netscape 4 was driven from the face of the earth by
some invisible cohort of vigilante web developers is quite fantastic.
Did this same self-righteous mob also drive IE 4 into oblivion (which
occurred while Netscape 3 was still being used in meaningful numbers)?

If lack of standards compliance is a reason for any particular browser
to die, then IE would have been stillborn. It is the most
'mollycoddled' of all browsers, particularly in regard to CSS.

Hoist with your own petard?

[...]

Oh, and it is usual practice in this forum to trim quotes to that part
being replied to.
--
Rob
Aug 1 '05 #17

P: n/a
RobG said the following on 7/31/2005 10:04 PM:
fox wrote:
[...]

So -- it's just about "lightweight solutions for lightweight browsers"
-- right?

Comply or Die worked against Netscape 4. So why not all the others?
Now it's "let's mollycoddle all these poor minority browsers to give
them a chance to survive?" Don't make me laugh.

That attitude is at once both ignorant and arrogant.


About as ignorant and arrogant as your reply? Read on before you get
offended.
Your notion that Netscape 4 was driven from the face of the earth by
some invisible cohort of vigilante web developers is quite fantastic.
Did this same self-righteous mob also drive IE 4 into oblivion (which
occurred while Netscape 3 was still being used in meaningful numbers)?
Netscape 4 was indeed driven into oblivion, but not just by developers.
It started with developers not supporting it, and then Netscape
realizing that the document.layers collection was a stupid idea from the
start and scrapping it in favor of modern practices. Ever tried to
address a nested layer (oh, say 3 deep) in NN4?
If lack of standards compliance is a reason for any particular browser
to die, then IE would have been stillborn.
That could also be said about other browsers, but I agree that IE is
about as far from being standards compliant as Firefox is. To find out,
test the code Richard posted:

var a = []
a[4251456798] = 'a';
a.reverse();

yeah, Firefox follows the ECMA quasi-standard, eh?

Every browser has it's flaws, some have more than others and Netscape 4
was the epitome of a flawed browser in it's approach and it's DOM.
It is the most 'mollycoddled' of all browsers, particularly in regard to CSS.


While that may be true, that is an argument for ciwas, not clj.

<--snipped parts I didn't reply to-->

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Aug 1 '05 #18

P: n/a
Randy Webb wrote:
RobG said the following on 7/31/2005 10:04 PM:
fox wrote:
[...]

So -- it's just about "lightweight solutions for lightweight
browsers" -- right?

Comply or Die worked against Netscape 4. So why not all the others?
Now it's "let's mollycoddle all these poor minority browsers to give
them a chance to survive?" Don't make me laugh.


That attitude is at once both ignorant and arrogant.

About as ignorant and arrogant as your reply? Read on before you get
offended.


I'm not offended, just annoyed that I replied at all. I agree with
all you say (above and [snipped] below). :-x

[...]

--
Rob
Aug 1 '05 #19

P: n/a
Dr John Stockton wrote:
[...]
so, for strings of the length in question, ISTM
reasonably likely that the overall time will be dominated by other parts
of the routine. If it matters, it should be tested.


i doubt it matters much in JS...

If there is doubt whether it matters, it should be tested; I did so.


Seems worth testing- below is a small example that tests method A using
custom objects and replace function, method B uses string operations and
sort. Random date strings are generated - not all dates are valid and
the range is not extensive, but neither factor affects the results.

The string method runs about 60 times faster, so if speed does matter,
you'd need a good reason to prefer the other.
<script type="text/javascript">
/* used to convert string months to digits */
var mos={ Jan:"01", Feb:"02", Mar:"03", Apr:"04", May:"05", Jun:"06",
Jul:"07", Aug:"08", Sep:"09", Oct:"10", Nov:"11", Dec:"12" };

/* used to generate month strings */
var moA = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];

var oracleDatesArray = [];

/* support functions, do not contribute to time */
function genDates ( a, n ) {
for ( var i=0; i<n; i++ ) {
a[i] =
addZ( RanSpan( 1, 31) ) + '-'
+ moA[ RanSpan( 0, 11 ) ] + '-'
+ addZ( RanSpan( 0, 5 ) );
}
}
function addZ( x ) {
return ( x<10 )? '0' + x : '' + x;
}
// Random functions from
// http://www.merlyn.demon.co.uk/js-randm.htm#FnB
function Random(N) {
return (N * (Math.random() % 1)) | 0;
}
function RanSpan(MinV, MaxV) {
return MinV + Random(MaxV - MinV + 1);
}

/* Object method using replace with function argument */
String.prototype.oracleDateValue = function() {
return this.replace(/(\d+)-(\w+)-(\d+)/,
function(s, p1, p2, p3) {
return "20" + p3 + mos[p2] + p1;
});
}

function oracleDateCompare(a,b) {
return a.oracleDateValue() - b.oracleDateValue();
}

/* plain string method */
function sortOdates( a ){
var aB, b = [];
var i = a.length
do {
aB = a[--i].split('-');
b[i] = '20' + aB[2] + '-' + mos[aB[1]] + '-' + aB[0];
} while ( i )
return b.sort();
}

// Generate random dates array
genDates( oracleDatesArray, 1000 );

// Do string method
var bS = new Date();
sortOdates( oracleDatesArray );
var bF = new Date();

// Do object method
var aS = new Date();
oracleDatesArray.sort( oracleDateCompare );
var aF = new Date();

alert(
'Object time: ' + (aF-aS)
+ '\nString time: ' + (bF-bS)
);

</script>
--
Rob
Aug 2 '05 #20

P: n/a
JRS: In article <hl****************@news.optus.net.au>, dated Tue, 2
Aug 2005 03:00:29, seen in news:comp.lang.javascript, RobG
<rg***@iinet.net.auau> posted :

Seems worth testing- below is a small example that tests method A using
custom objects and replace function, method B uses string operations and
sort. Random date strings are generated - not all dates are valid and
the range is not extensive, but neither factor affects the results.

The string method runs about 60 times faster, so if speed does matter,
you'd need a good reason to prefer the other.

It would have saved me time if you had described what you were sorting,
and how. AFAICS :

Your date array appears to hold entries such as 13-Apr-05.

Your string sort first converts those to 2005-04-13 (the hyphens are a
waste of time, at least for a large array or if the output dates are to
be reformatted; and so is the 20) and then sorts. The sort itself is as
efficient as can be for strings.

Your object sort, however, will do o(>N) comparisons, each calling a
javascript compare function, which twice calls a conversion function,
each of which calls a RegExp replace which calls a function which
returns a string; the strings are subtracted, which entails conversions
to Number. Naturally it is a slow method.

An efficient Object sort would preprocess the date array into a Date
Object array, and use a comparison function that subtracts the Objects,
which is subtracting their internal milliseconds since UTC 1970.0. It
will be much quicker than yours.

A really efficient sort would preprocess the date array into an array of
<Date Object>.valueOf() and do the default sort on Numbers - if only
Javascript could sort Numbers!!

For large enough arrays, one might try new Date().valueOf().toString(36)
which generates an 8-character string for years 1973 to 2058. Note that
by changing the 20 to something bigger or by adding to valueOf() one can
handle a wider span of years; one more digit gets to 5188, another to
117829, another to NaN.

Or one could take Y M D, compress that as, say, (Y*12+M)*31+D, convert
that to a fixed-length string, and sort those.

So you've proved that a string method coded almost optimally is very
much better than a cumbersome implementation of sorting with Objects.
In sorting arrays which are large enough for speed to be a concern, the
prime aim must be to minimise the work done by the user-written
comparison function; and the greatest minimisation is not to have one at
all.
Random instants can be efficiently generated by something like
new Date(RanSpan(11000, 44000)*864e5)

--
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.
Aug 2 '05 #21

P: n/a
fox
The reason I am so late in responding is that I had many years of source
code to go through in order to accurately verify the origin of my idea
so that there could be no questions. I also had to do a good deal of
research on many topics as a "refresher" since nitpicking seems to be
the order of the day.

Dr John Stockton wrote:
JRS: In article <dc**********@news.datasync.com>, dated Sat, 30 Jul
2005 20:54:00, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :

Dr John Stockton wrote:
JRS: In article <dc**********@news.datasync.com>, dated Fri, 29 Jul
2005 03:43:07, seen in news:comp.lang.javascript, fox
<sp******@fxmahoney.com> posted :
comparing strings no doubt takes longer than comparing numbers.
Perhaps so. But the comparison operator should be implemented at the
ASM level or similar;
Not relevant -- no access to asm level in js.

ASM level or similar - which includes any efficiently-compiled high
level language - is what should do the work of executing javascript
operations. We have no direct access, agreed.

so, for strings of the length in question, ISTM
reasonably likely that the overall time will be dominated by other parts
of the routine. If it matters, it should be tested.


i doubt it matters much in JS...

If there is doubt whether it matters,


if there is a doubt -- chances are very good it doesn't matter. from a
UI point of view (something you know very little about) a few
microseconds here and there are *negligible*.
it should be tested; I did so.
I think you're lying... I think you simply "reasoned" it -- JUST LIKE I DID
With 8-character strings, using the quickest test loop I know, I find
the loop for comparison of equal 8-character Strings to be about 10%
slower than that for the corresponding Numbers, loop overhead being
about 20%. Other browsers are likely to differ.
not relevant... you didn't "get it"... and you "conveniently" cut off "I
used to do it in C"! This can't be done in JS... you wasted your time
"testing" this in JS... at the "engine level" of JS's sort routine is
STILL the character by character comparison (I checked) and whether you
chop the string in sections of 8 or not, you still have string data types.

You miss the point.


nice try...

One can convert an 8-character String to Number, if
the string be a string of decimal digit characters. Sort speed of
Strings will not depend on the exact identity of the characters in them;
so one can meaningfully compare the comparison speed of Strings like
"12345678" with that of Numbers like 12345678, each being adequately
representative of the general case.
clever trick paraphrasing my illustration and giving it back to me as if
it were your idea...

I can verify that specific JavaScript source code of mine that uses
packed date format goes back to feb 98 (and C source back to 95)... and
at that, it was the file modification date of the "final version." The
file was available for public access as of feb 98 and is verifiable that
it was availabe in 1998 via Google groups (a ref. to qdate in July of 98
and the source code and an explanation of the routines, and showing
specifically the "packed 32-bit integer with the following format:
yyyymmdd" in Nov 98) ["true packing"]

Whatever else you think of this nine year old code, don't pretend to
tell me like I don't know it backwards and forwards. it's *insulting*


For sorting a large number of dates, one should address the question of
whether it is worthwhile to convert the dates to/from a more efficiently
sortable form before/after sorting.
see... now if you had tested it, this wouldn't even be a question.
That conversion takes time o(N)
whereas sorting will be >o(N).
*VERY IMPRESSIVE* quoting the "books" on sort efficiency... however
inaccurately: that's supposed to be a capital O ("complexity") [ the
notation is even *referred* to as "big-o"]

if JS uses Quick Sort (which I believe it does - but it is very
difficult digging around the source code at mozilla and i have not been
able to verify through other sources, *to this point* -- no info on
JScript either)... it has a worst case efficiency of O(n^2)

Avg time for a quick sort is: O(n*ln(n)); so yeah... that would be >O(n)
Hence it is worth (slightly) converting
from String to Number for a sufficiently large number of dates, if my
result is typical.

I thought you were a "die-hard" IE4 user... only mozilla/gecko has this
advantage (and, as much as i *hate* to say it: mozilla doesn't count for
much in the real world).

if we had BOTH read ECMA-262, we would have seen that the first thing
the sort algorithm does is "call toString" on both a and b... converting
to number to have js convert it to string is a waste of time.

In sorting Date Objects, things are a little different; Date Objects
store dates as Number, but a non-default Sort is needed, so here there
is the added overhead of calling (>o(N) times) a simple sort function;
however, the conversions between Date Object and Number are simpler,
involving only administrative processing.
Sorting Date Objects is even MORE surprising...
This was my test:

(unbiased -- no "type" conversions during sort)

10000 random "yyyymmdd"
10000 random yyyymmdd (Number)
10000 random Date

since benchmarking random data sorts in Javascript is subject to a good
bit of variation, i'll state an "average" rounded result indicative of
each sort test:

IE6

"yyyymmdd" no compare function 90ms cmp: a < b 6300ms
yyyymmdd no compare function 140ms cmp: a - b 7400ms
Date ---------------------------- cmp: a - b 22500ms
Date ---------------------------- cmp: getTime 32000ms
Firefox

"yyyymmdd" no compare function 60ms cmp: a < b 450ms
yyyymmdd no compare function 1440ms cmp: a - b 350ms
Date ---------------------------- cmp: a - b 3100ms
Date ---------------------------- cmp: getTime 4900ms

800MHz P4 win2k
Defies logic... doesn't it?!? Numbers vs Strings, that is...

[*
cmp: a < b means: return a < b ? -1 : 1
cmp: a - b means: return a-b;
cmp: getTime means: return a.getTime() - b.getTime()
*]

**after about 1000 elements, quicksort's efficiency rapidly decays,
according to sources I was able to find "on such short notice"**

I also tried prototyping a sort routine and the abbreviated date string
(iso basic) into the Date object -- results tended to be even worse than
just sorting the Date objects outlined above.

But as it turns out, my original routine converting oracle database
dates into "yyyymmdd" was the MOST efficient way to go, as far as
anything that has been discussed in this thread... keeping the
yyyy-mm-dd format will cost a couple of extra microseconds per pass.


The rest of your response is best ignored.

then I can add anything I want for posterity here... heh...

charlatan... carpetbagger (US def.)...
.... until you bring your incessantly self-referred js code up to
reasonably modern standards, you are just being mean to the beginners...
after this thread i seriously wonder if you are even capable -- do you
really know or remember what all those single-letter variable names
stand for anymore? (many have no relationship to their function.) Did
you not understand the algorithms when you copied them from the old
BASIC texts? not even Knuth codes like that anymore. Wirth was/is an
advocate for *clearly readable* source code. Pascal was designed to
"read like english." when *you* invoke his name, you insult *him* AND
the language.

also, what's the deal with Math.floor(Math.random() % 1)? (i saw that
robG diligently copied it from your site...bet that flattered you.) i
vaguely remember something about that bug from years and years ago. i
can no longer find any valid current reference to anything like this
save for people copying your code. from somebody so obsessed with
efficiency, this seems a little unusual.

you should also revisit your "Deal":

1) you cannot distribute the same set to each recipient
2) you cannot isolate subsets from within
the function creating the set or its order
3) save for a very few solitaires, the entire set is rarely dealt

it's really only a shuffle...
clean your own house before you criticize others'


Aug 4 '05 #22

P: n/a
fox <sp******@fxmahoney.com> wrote:
mozilla doesn't count for much in the real world).


Well, depends on the world in question. The opposite of your "never seen it
at a customer" is e.g.

<URL:http://www.adtech.de/NewsPresse/framepresse.php?lang_id=de&node=4&current=193>
or
<URL:http://www.xitimonitor.com/etudes/equipement10.asp>

Bye,
Martin
Aug 4 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.