Re: FAQ Topic - How do I format a date with javascript? (2009-06-01)



Dr J R Stockton wrote:
In comp.lang.javascript message <h0t2oi$je2$1@xxxxxxxxxxxxx
september.org>, Fri, 12 Jun 2009 01:14:07, Garrett Smith
<dhtmlkitchen@xxxxxxxxx> posted:
Dr J R Stockton wrote:
In comp.lang.javascript message <h0raf8$ikp$1@xxxxxxxxxxxxx
september.org>, Thu, 11 Jun 2009 09:13:27, Garrett Smith
<dhtmlkitchen@xxxxxxxxx> posted:






The entry:

"11.1 How do I get my browser to report javascript errors?"

covers the subject of browsers reporting errors.

But it says nothing about the effect of calling throw.


Technically, |throw| is a Statement, and is not called.

Exception handling could find its place in the FAQ.



I do not know KDF9, but "throw" is a basic computer science term nowadays.

Of course; but there are still two different types of throw call in the
Standard; the reserved word, and the action internal to failing
routines. a (CtrlF-type) search cannot distinguish. If the reserved
word had been thro, raise, abort, etc., the clash would not have
occurred. It's like the difficulty in talking about undefined results
in a context where "undefined" can mean an Object type, the value of an
object of that type, or its literal representation in code.


Throw is a flow-of-control behavior. Whether it happens by intent of the program or by accident does not change that.


Using "alert" would be better; one knows what it will do, and it's an
obvious candidate for replacement if unsuited to circumstances.
Consider it as a place-holder for whatever suits the application.

No! The alert method has no place in such code. Calling alert there
would be a bad side effect. It would be awkward for the caller to
handle that gracefully. Consider:-

var realAlert = window.alert;
window.alert = logError;
formatDate( myDate );
window.alert = realAlert;

That is awful.

Anyone who redefines something provided by the system must look to see
whether that object is used elsewhere in the code.


My point was that that would be the only way to "catch" an |alert|. An error can be caught by standard exception handling mechanism.

Anyone taking code from a FAQ should read it first, and should test it
before embedding it deeply in other code. Writing alert(string) is a
concise and reliable way both of indicating a problem on initial test
and showing where other error handling might be substituted. Just
quitting is not satisfactory. Returning a string such as "Year error"
instead of a YYYY-MM-DD string also works; it will be noticed.


It would also be noticed to return "". Not an ISO-8601 format, but noticeable.

In production code, the error should never be allowed to occur.


Absolutely not. It should be checked.


AFAIK, there is only one "invalid" value that a Date Object
can have, NaN. If it is used, there should be a warning that
new Date(NaN).toString() is browser-dependent.
The return value of Date.prototype.toString itself is implementation-
dependent and that is stated in the specification which is linked.

It is, for non-NAN objects, always a readable representation of the
date; the result for NaN varies more than that.


The result is specified as being implementation-dependent. The format varies between implementations.

[...]


But NaN is a valid date in JavaScript,
one which is off-calendar. It should not lightly be called invalid.

It's like a "Null Object".

It must not be called that, though.





The ISO 8601 Extended format can be understood internationally, without
xxx ^An (there are more than one) (don't use Any[0])
world-wide ---> xxxxxxxxxxxxxx
ISO 8601 Extended formats can be...

No; that definitely implies that all of them can be.

or

[Most|Common|Many] 8601 Extended formats can be...

or even

Many common ISO 8601 Extended formats can be..

Obvious minor variations such as year outside 0000-9999 and the presence
of time fields apart, there are not enough extended formats to justify
"Many".




So going with "Common ISO 8601 Extended formats..."

[...]

Look at the return statement:-

| return yyyy + "-" + mm + "-" + dd;

The intent of the code and code is doing could not be any clearer.

Yes, but that would still apply if year & yyyy were replaced by Y, mm by
M, dd by D. The comment must say that the output is YYYY-MM-DD, which
makes all else obvious.



I think the yyyy variable makes the code a little easier to read. I don't find it hard to read:-

return year + "-" + mm + "-" + dd;

- but I do find it clearer as:-

yyyy + "-" + mm + "-" + dd;

- which does not change |year| to be a string.


Never use a local date/time for a non-local event. Instead, use UTC, as
in ISO 8601 YYYY-MM-DDThh:mm:ssZ ( Z is the only letter suffix).
?? postfix ??
Don't those two words mean the same thing?

No. A suffix is below, an index or superfix above - as in HTML <sub>

that's subscript.
<sup>.

superscript.

A prefix is before, a postfix is after, both on-the-line.
Suffix in this context will be understood, but postfix is correct.


[...]


We went into validation rather thoroughly before. Read the archives.

OK.


However, the simpler pattern posted earlier is easier to read and
perhaps more suitable for the FAQ.

The pattern should ignore leading and trailing whitespace only and not
try and find a date format buried in a string. \s is probably enough
here. I know that implementations are not consistent with each other or
the specification on \s and we have discussed the Mongolian vowel
separator and no-break space (\u00a0).

I wrote, legibly enough, "at the very minimum", in order to show only
what was needed for validation by checking getMonth to work. But why
not use \D, which correctly accepts ALL whitespace varieties and permits
finding dates in strings containing other non-digits? The purpose is to
validate the date indicated, not the ISO compliance.


It expands the functionality of what the method does to something it is not designed or tested for. I don't want the method to guaranteed that. Allowing leading/trailing space only keeps it simpler.

Including "\D" would match: YYYY-MM-DDT and the function would not do anything with anything following that "T".

Revised:-

/**Parses string formatted as YYYY-MM-DD to a Date object.
^a xxxxxxxxxxxx superfluous
* If the supplied string does not match the format, an
xxxxxxxx superfluous
* invalid Date (value NaN) is returned.
* @param {string} dateStringInRange format YYYY-MM-DD, with year in
No need to specify the format twice, especially in a language delivered
as source.
* range of 0000-9999, inclusive.
* @return {Date} Native Date object representing the string.
*/
function parseISO8601( dateStringInRange ) {

Following your earlier argument, the function name should indicate which
ISO format type. InRange is superfluous.


The "inRange" was to indicate that there is a range. That range is not indicated, but it is 0000-9999.

Do you have in mind a better name for the function that would indicate that?


formatDateToExtendedYYYYMMDD
- hard to read with all the long run of upper case letters. Even with camelCase, it is an eyesore: formatDateToExtendedYyyyMmDd.

Underscore could possibly work:
formatDateToYYYY_MM_DD

- hard to read and does not indicate range.

var date = new Date(NaN),
isoExp, parts;
isoExp = /^\s*([\d]{4})-(\d\d)-(\d\d)\s*$/;

No general need to check field lengths, except for not exceeding DD.


The pattern is YYYY-MM-DD, and that is what the regexp checks (and allows whitespace on the ends).

parts = isoExp.exec(dateStringInRange);

if(parts) {
date.setFullYear(parts[1], parts[2] - 1, parts[3], 0, 0, 0, 0);

It seems unwise to use arguments that ECMA 3 & FD 5 specify are not

Right.

there. The length of setFullYear is 3 -
new Date().setFullYear.length gives 3.

if(parts[2] != date.getDate()
|| parts[1] != date.getMonth() + 1
|| parts[0] != date.getFullYear() ) {

You clearly have not understood. All this is in the archives, and on my
site. There is no need to test getDate, since if the value given is
outside the month but in 00-99 (guaranteed by RegExp) then the getMonth
test must fail. There is no need to test the Year either, since
setFullYear does not add 1900 to years under 100.


Checking getMonth is all that is needed. Simpler and faster.

function parseISO8601( dateStringInRange ) {
var date = new Date(NaN),
isoExp, parts;
isoExp = /^\s*([\d]{4})-(\d\d)-(\d\d)\s*$/;
parts = isoExp.exec(dateStringInRange);

if(parts) {
date.setFullYear(parts[1], parts[2] - 1, parts[3]);
if( parts[1] != date.getMonth() + 1 ) {
date.setTime(NaN);
} else {
date.setHours(0, 0, 0, 0);
}
}
return date;
}

Garrett
--
The official comp.lang.javascript FAQ:
http://jibbering.com/faq/
.



Relevant Pages

  • Re: Query Help Please! Is a Weekly data format Possible?
    ... There are a number of string formats that work, ... "Tom Ellison" wrote: ... Is there a way to have this query group the data in a weekly format ...
    (microsoft.public.access.queries)
  • Re: Another PL/I cant
    ... not a function that converts a string to its length expressed ... CVF apparently has real issues with this stuff. ... no deficiencies and the other way is to make it so complicated ...
    (comp.lang.fortran)
  • Re: Access Databse "Select * from Bilag Where Mdates Between #1/1/2006# And #31/1/2006#"
    ... date formats were always yyyy/mm/dd. ... Function fDateToString(byVal adtmDate as Date) as String ... Dim lsEnclosure as String ...
    (microsoft.public.dotnet.languages.vb)
  • RE: Fixed Length
    ... match these formats, but rather pull the existing, normal, formats from the ... and run a function to build that information into a string that you ... length and the total lenght of all the fields has to be 100 characters. ... JobId (8 char) ...
    (microsoft.public.access.modulesdaovba)
  • Re: FAQ Topic - How do I format a date with javascript? (2009-06-01)
    ... earlier ISO standards favoured Y M D order. ... There may be only two Complete representations for a calendar date, there is still room to have representations with reduced accuracy. ... YYYY-MM-DD Complete Representation ... for parsing and formatting ISO 8601 formats. ...
    (comp.lang.javascript)