FAQ Topic - How can I create a Date from a String? (2009-10-05)

D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Fri, 16 Oct 2009 22:32:44, Garrett Smith
How does this look?

As an answer to the Subject question : ridiculous.


function formatDate(dateInRange) {
var year = dateInRange.getFullYear(),
isInRange = year >= 0 && year <= 9999,
yyyy, mm, dd;
if(!isInRange) {
throw RangeError("formatDate: year must be 0000-9999");
}
yyyy = ("000" + year).slice(-4);
mm = ("0" + (dateInRange.getMonth() + 1)).slice(-2);
dd = ("0" + (dateInRange.getDate())).slice(-2);
return yyyy + "-" + mm + "-" + dd;
}

Keep at least that range. If anyone wants a reduced range, the required
change is obvious. This is a FAQ for reading intelligently, not a
library for executing.

"isInRange" is unnecessarily long; "ok" suffices. Better :

if (year<0 || year>9999) { throw ...

It's not nice to have 0/0000 and 9999 coded twice, once as Number and
once in String.

"Throw" should not be used, since how to use it is not obvious and there
is no example in the FAQ.

This is slightly shorter and is faster in Firefox :

mm = (101 + dateInRange.getMonth() + "").slice(-2);

Pedagogically, it would be better to do the lengthening with a function
(or a Method of Number). Such a function would be useful in presenting
times and could be used for currency. This is a general 2-digit Leading
Zero function, and can be simplified (untested) if it is certain that
its argument will not be null or negative :

function LZ(n) { return (n!=null&&n<10&&n>=0?"0":"") + n }
function LZ(n) { return (n<10?"0":"") + n }

Really, the routine should accept all dates within Date Object range.
It is much easier to simplify a general routine than to generalise a
simple routine.



Reverting to the first article of the thread : the comment says what
happens if the string dies not match the format YYYY-MM-DD, but it does
not actually say what happens if the digits supplied are incompatible
with the Gregorian Calendar. At least, change the line to

if (month != date.getMonth() + 1) { // validate numerical values

Goodman, Flanagan, ISO/IEC 16262, ECMA 262 FD5, Asen Bozhilov, the
recently-disparaged old Netscape MAN-type page (generally), even
<http://www.nasa.gov/js/195153main_countdownclock.js> - they all put a
space between "if" & "("; the FAQ should do so likewise. It improves
legibility.
 
G

Garrett Smith

Johannes said:
Johannes Baagoe :

Garrett Smith :
Who is the user? The person copy-pasting "formatDate" or the end
user who is interacting with the browser?

Both. Neither is likely to understand without some extra tuition what
0000-05-01 means. (Those who say "First of May in the last year before
the Common Era, of course!" are unlikely to copy-paste something they
don't understand.)
Regardless, the year 0 issue has been discussed here previously.
ISO 8601 explicitly lists year 0000.

I know. It means 1 BC, which many people call "-1", not "0". Hence a
likely offset of one between the year they code and and the year they
mean. This affects not only that particular year, but all previous
years as well, that is, all years BCE. Since negative years are already
rejected by formatDate, I suggested that rejecting the sole remaining
year before the Common Era would hardly make formatDate less useful :
a date in that year is most likely an error.

Further, using "0000-05-01" as an xs:date in an XQuery request yields
an "Invalid lexical value [err:FORG0001]" error which may be hard
to figure out. That means that people who use ECMAScript to interact
with XML databases should wrap calls to formatDate in a special test,
unless the published version is changed as per my suggestion, or
they are smart enough to remove the offending equal sign themselves
in their private version. I trust them to figure it out eventually,
but I still fail to see why accommodating the last year BCE should
be more important.

XML Schema[1] States:
Note:
| The date and time datatypes described in this recommendation were
| inspired by [ISO 8601]. '0001' is the lexical representation of the
| year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD").
| There is no year 0, and '0000' is not a valid lexical representation.
| '-0001' is the lexical representation of the year 1 Before Common Era
| (1 BCE, sometimes written "1 BC").
[...]

| [ISO 8601] makes no mention of the year 0; in [ISO 8601:1998 Draft
| Revision] the form '0000' was disallowed and this recommendation
| disallows it as well.

That would mean that year 1 BC, as written 0000 in ISO8601:2000
and ISO8601:2004(E) is written -0001.

That's a bug in the XML Schema spec.

I can't find where 0000 is disallowed anywhere in ISO8601:1998, nor can
I understand why the XML Schema is referencing that old spec, which was
superseded ISO8601:2000 and ISO8601:2004(E).
However, if the fact that the issue has been discussed means that it
must not be re-examined, or if restricting formatDate to the Common
Era without making an exception for the last year before has been
considered and rejected, I won't insist any longer.
The entry mentions ISO 8601 and links to ISO8601:2004(E). Is mentioning
a different representation range for XML Schema important?

Perhaps a small note at the bottom of that entry:
Year 0000 is not recognized by XML Schema or xs:date.

[1]http://www.w3.org/TR/xmlschema-2/#dateTime
 
T

Thomas 'PointedEars' Lahn

Garrett said:
XML Schema[1] States:
Note:
| The date and time datatypes described in this recommendation were
| inspired by [ISO 8601]. '0001' is the lexical representation of the
| year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD").
| There is no year 0, and '0000' is not a valid lexical representation.
| '-0001' is the lexical representation of the year 1 Before Common Era
| (1 BCE, sometimes written "1 BC").
[...]

| [ISO 8601] makes no mention of the year 0; in [ISO 8601:1998 Draft
| Revision] the form '0000' was disallowed and this recommendation
| disallows it as well.

That would mean that year 1 BC, as written 0000 in ISO8601:2000
and ISO8601:2004(E) is written -0001.

That's a bug in the XML Schema spec.

It evidently isn't:

,-<http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#noYearZero>
|
| D.3 Deviations from ISO 8601 Formats
| [...]
| D.3.2 No Year Zero
|
| The year "0000" is an illegal year value.
I can't find where 0000 is disallowed anywhere in ISO8601:1998, nor can
I understand why the XML Schema is referencing that old spec, which was
superseded ISO8601:2000 and ISO8601:2004(E).

The cause is pretty obvious:

,-<http://www.w3.org/TR/1999/WD-xmlschema-2-19990924/>
|
| XML Schema Part 2: Datatypes
|
| W3C Working Draft 24 September 1999

Apparently nobody updated the reference yet. Even the link is dead now.
The entry mentions ISO 8601 and links to ISO8601:2004(E). Is mentioning
a different representation range for XML Schema important?

Perhaps a small note at the bottom of that entry:
Year 0000 is not recognized by XML Schema or xs:date.

Works as designed.

However, I wonder what all of this has to do with ECMAScript, let alone the
FAQ entry. That said, I find it pretty silly to restrict the interpretation
of YYYY to a decimal four-digit display. In all applications I know, it
means four or more decimal digits so that the century of the year, according
to the Gregorian Calendar, is accurately represented. I thought we had
learned something from the Y2K bug, but apparently not. Incidentally, in
printf-based date formatting, which I prefer, `%Y' represents the full year
(including the full century).


PointedEars
 
G

Garrett Smith

Thomas said:
Garrett said:
XML Schema[1] States:
Note:
| The date and time datatypes described in this recommendation were
| inspired by [ISO 8601]. '0001' is the lexical representation of the
| year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD").
| There is no year 0, and '0000' is not a valid lexical representation.
| '-0001' is the lexical representation of the year 1 Before Common Era
| (1 BCE, sometimes written "1 BC").
[...]

| [ISO 8601] makes no mention of the year 0; in [ISO 8601:1998 Draft
| Revision] the form '0000' was disallowed and this recommendation
| disallows it as well.

That would mean that year 1 BC, as written 0000 in ISO8601:2000
and ISO8601:2004(E) is written -0001.

That's a bug in the XML Schema spec.

It evidently isn't:

XML Schema states:

"[ISO 8601] makes no mention of the year 0;"

That is wrong; ISO8601:2000 explicitly mentions 0000.

ISO8601:2004(E)
| 4.1.2.1 General
| In expressions of calendar dates
|
| calendar year is, unless specified otherwise, represented by four
| digits. Calendar years are numbered in ascending order according to
| the Gregorian calendar by values in the range [0000] to [9999]. Values
| in the range [0000] through [1582]

ISO8601:2000
| 5.2.1 Calendar date
|
| ...year is generally represented by four digits; years are numbered in
| ascending order according to the Gregorian calendar by values in the
| range [0000] to [9999]. ...
Works as designed.

However, I wonder what all of this has to do with ECMAScript, let alone the
FAQ entry. That said, I find it pretty silly to restrict the interpretation
of YYYY to a decimal four-digit display. In all applications I know, it
means four or more decimal digits so that the century of the year, according
to the Gregorian Calendar, is accurately represented. I thought we had
learned something from the Y2K bug, but apparently not. Incidentally, in
printf-based date formatting, which I prefer, `%Y' represents the full year
(including the full century).

There is some value in mentioning that XML Schema deviates from ISO8601,
and also in linking to that. Does it add extra clutter?

The reason given for XML Schema disallowing year 0 is that ISO8601 does
not mention year 0, but that is false. Looks like somebody fucked up.
 
G

Garrett Smith

Hans-Georg Michna said:
I did understand the capitalized Date, but I admit that I also
stumbled over the slight potential for misunderstanding.

I guess this cannot be argued very well, because the perception
varies. I don't think this discussion will lead anywhere.
Fine. "Date object" it is.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Thomas said:
Garrett said:
XML Schema[1] States:
Note:
| The date and time datatypes described in this recommendation were
| inspired by [ISO 8601]. '0001' is the lexical representation of the
| year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD").
| There is no year 0, and '0000' is not a valid lexical representation.
| '-0001' is the lexical representation of the year 1 Before Common Era
| (1 BCE, sometimes written "1 BC").
[...]

| [ISO 8601] makes no mention of the year 0; in [ISO 8601:1998 Draft
| Revision] the form '0000' was disallowed and this recommendation
| disallows it as well.

That would mean that year 1 BC, as written 0000 in ISO8601:2000
and ISO8601:2004(E) is written -0001.

That's a bug in the XML Schema spec.

It evidently isn't:

XML Schema states:

"[ISO 8601] makes no mention of the year 0;"

That is wrong; ISO8601:2000 explicitly mentions 0000.

But `[ISO 8601]' does not refer to ISO8601:2000 there, does it?
ISO8601:2004(E)
[...]
ISO8601:2000

Irrelevant to show the veracity of the statement above. You have not quoted
the most relevant part:

| [...] in [ISO 8601:1998 Draft Revision] the form '0000' was disallowed and
| this recommendation disallows it as well. However, [ISO 8601:2000 Second
| Edition], which became available just as we were completing version 1.0,
| allows the form '0000', representing the year 1 BCE. [...]
[...]
There is some value in mentioning that XML Schema deviates from ISO8601,
and also in linking to that. Does it add extra clutter?

Are you writing an XML Schema FAQ? Has this NG "xml" in its name?
The reason given for XML Schema disallowing year 0 is that ISO8601 does
not mention year 0,

No, it is not. You misunderstand
<http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/>, section 3.2.7,
and ignore
but that is false.

Non sequitur.
Looks like somebody fucked up.

Yes; *you* did. And unless the subject is going to be something JS/ES-
related again, it's EOD for me.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Mon, 19 Oct 2009 17:33:29, Garrett Smith
The entry mentions ISO 8601 and links to ISO8601:2004(E). Is mentioning
a different representation range for XML Schema important?

Perhaps a small note at the bottom of that entry:
Year 0000 is not recognized by XML Schema or xs:date.

It is not the business of a general purpose date-output routine, as this
should be, to pay much heed to the various preferences of petty bodies
or specialised systems. It should heed, but need not be absolutely
bound by, ISO 8601. And it should either support, or be readily
adaptable to support, field orders other than Y M D, since those may be
required for display.

Its prime purpose should be to support (proleptic Gregorian) YYYY-MM-DD
for current years; all years in 1000-9999 are equally easy.

It should also support earlier years, 0-999, in 4-digit form. That
reduces confusion between years (for example) 98 & 1998, 10 & 2010 - and
those may unintentionally occur in Objects.

And it should never, for any value that a Date object can (rightly or)
contain, give a string which actually represents a non-corresponding
year.

It should, therefore, give, as well as the obvious MM & DD, Math.abs of
the year, toString-ed and with leading zeroes added to bring the number
of digits, if fewer, up to four. And in front of that, it should put a
representation of sign : "-" for negative years, and a user-chosen one
of "+", " ", "", for non-negative years.

It can be described as compliant with ISO 8601 for 0000-9999 (with sign
""), with XML for 0001-9999, etc.

In most applications, which means at least business and ordinary
leisure, there is no need to make allowance for years outside 1000 to
9999. Therefore, the code for those extremes should be easily
removable. There is no need to test the year-range within the routine;
that is the business of the application.

Hoteliers, for example, do not generally accept bookings for dates
before the present day; undertakers (morticians) are commonly reluctant
to consider dates of death after the present day.
 
G

Garrett Smith

Thomas said:
Garrett said:
Thomas said:
Garrett Smith wrote:
XML Schema[1] States:
Note:
| The date and time datatypes described in this recommendation were
| inspired by [ISO 8601]. '0001' is the lexical representation of the
| year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD").
| There is no year 0, and '0000' is not a valid lexical representation.
| '-0001' is the lexical representation of the year 1 Before Common Era
| (1 BCE, sometimes written "1 BC").
[...]

| [ISO 8601] makes no mention of the year 0; in [ISO 8601:1998 Draft
| Revision] the form '0000' was disallowed and this recommendation
| disallows it as well.

That would mean that year 1 BC, as written 0000 in ISO8601:2000
and ISO8601:2004(E) is written -0001.

That's a bug in the XML Schema spec.
It evidently isn't:
XML Schema states:

"[ISO 8601] makes no mention of the year 0;"

That is wrong; ISO8601:2000 explicitly mentions 0000.

But `[ISO 8601]' does not refer to ISO8601:2000 there, does it?
ISO8601, as listed in XML Schema norm refs section, refers to
the 1998 revision, which is listed as a reference twice, once as [ISO
8601] and once as [ISO 8601:1998 Draft Revision].

That is a mistake.

(possibly an editorial mistake, based on copy paste errors).

Where is the ISO 8601:1998 Draft Revision that XML Schema bases this
claim on? DThe official version of ISO8601:1998 does not support that
claim. ISO8601:2000 contradicts it.

The XML Schema specification references [ISO 8601:2000 Second Edition],
too, where convenient to do so.

Comparing two very close draft of XML Schema, the normative reference;
W3C Candidate Recommendation 24 October 2000 lists
http://www.w3.org/TR/2000/CR-xmlschema-2-20001024/#ISO8601

| ISO 8601
| ISO (International Organization for Standardization).
| Representations of dates and times, 1988-06-15. Available at:
| http://www.iso.ch/markete/8601.pdf
| ISO 8601 Draft Revision
| ISO (International Organization for Standardization).
| Representations of dates and times, draft revision, *1998.*


The W3C Proposed Recommendation 16 March 2001 lists:
| ISO 8601
| ISO (International Organization for Standardization).
| Representations of dates and times, 1988-06-15. Available at:
| http://www.iso.ch/markete/8601.pdf
| ISO 8601 Draft Revision
| ISO (International Organization for Standardization).
| Representations of dates and times, draft revision, *2000*.

That looks like a copy paste error to me.

Later, the reference to ISO8601:2000 was listed as a reference to XML
Schema, which states:

| A number of external commentators have also suggested that '0000' be
| allowed, as the lexical representation for 1 BCE, which is the normal
| usage in astronomical contexts.

Once the spec was published, it was not undoable, and became an
official deviation of ISO8601.
ISO8601:2004(E)
[...]
ISO8601:2000

Irrelevant to show the veracity of the statement above. You have not quoted
the most relevant part:

| [...] in [ISO 8601:1998 Draft Revision] the form '0000' was disallowed and
| this recommendation disallows it as well. However, [ISO 8601:2000 Second
| Edition], which became available just as we were completing version 1.0,
| allows the form '0000', representing the year 1 BCE. [...]

Looks like XML Schema was still a Working Draft on 2000-05-02.
<URL: http://www.w3.org/TR/2000/WD-xmlschema-2-20000922/ >

This became a Recommendation on 2001-05-02.

If this is true, then the ISO8601:2000 should have been used for
reference. ISO8601:1998 was obsolote at that time (and so was the
Draft Revision).

Those earlier XML Schema revisions refer to ISO8601:1998 and to
ISO8601:2000 draft.
<URL: http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#ISO8601 >

Later revision of XML Schema mentions ISO8601:1998 draft.
[...]
There is some value in mentioning that XML Schema deviates from ISO8601,
and also in linking to that. Does it add extra clutter?

Are you writing an XML Schema FAQ? Has this NG "xml" in its name?

No. It is a deviations/quirk to ISO 8601.

Another poster (Baagoe) brought it up and it seems relevant to web
development. An ISO8601 string might be sent to the server, for storing
in an SQL or XML database (the FAQ does mention SQL Date).

And so it is at least relevant to someone. I'll post up a whole draft
that includes it and take feedback on it.
No, it is not. You misunderstand
<http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/>, section 3.2.7,
and ignore


Non sequitur.

Did I? About what? That the deviation exists? I got that. Year "-0001"
is *not* the year 0, not in ISO8601.

XML Schema, dated October 2004, reference an obsolete 1998 *draft* that
was superseded by an official 1998 spec, which in turn was superseded by
a 2000 spec, which in turn has been superseded by a 2004 spec.

I can find no justifiable reason for referencing a 1998 draft,
superseded at the time XML Schema was published, and I cannot find that
draft to verify the claim. Can you?
 
G

Garrett Smith

Dr said:
In comp.lang.javascript message <[email protected]
september.org>, Fri, 16 Oct 2009 22:32:44, Garrett Smith


As an answer to the Subject question : ridiculous.

How does the code look? Seems to be fine, based on feedback so far.

It is shorter and faster than the previous version.
Keep at least that range. If anyone wants a reduced range, the required
change is obvious. This is a FAQ for reading intelligently, not a
library for executing.

"isInRange" is unnecessarily long; "ok" suffices. Better :

isInRange is more descriptive.
if (year<0 || year>9999) { throw ...

It's not nice to have 0/0000 and 9999 coded twice, once as Number and
once in String.

"Throw" should not be used, since how to use it is not obvious and there
is no example in the FAQ.

You brought this up before. "throw" is a flow of control statement,
(like if, else, etc). The FAQ does not explain those.

A section on Functions would be more valuable.

Function Expression/Declaraion/Statement questions are still common,
after all these years. Misconceptions and falsehoods are widely
published online and in books.

The article Kangax wrote on functions statements could be linked from
that, and there is quite a bit of information linked from within there.
This is slightly shorter and is faster in Firefox :

mm = (101 + dateInRange.getMonth() + "").slice(-2);

Is it? I didn't notice a difference in speed.
Pedagogically, it would be better to do the lengthening with a function
(or a Method of Number). Such a function would be useful in presenting
times and could be used for currency. This is a general 2-digit Leading
Zero function, and can be simplified (untested) if it is certain that
its argument will not be null or negative :

function LZ(n) { return (n!=null&&n<10&&n>=0?"0":"") + n }
function LZ(n) { return (n<10?"0":"") + n }

Abbreviated function name in constant case. We're not doing that.
Really, the routine should accept all dates within Date Object range.
It is much easier to simplify a general routine than to generalise a
simple routine.

Any date? I recall previously you thought capping at 9999 was sufficient
for most cases (and that was agreed on).

±YYYYY-MM-DD is not large enough for Astronomy, or other sciences.

Years 0-9999 represent a widely recognized range and fit the most common
ISO8601 format (poor XML Schema deviates with year 0).

Expanded range requires a +/- char. It is less portable to exchange
formats that do not recognize that format. Changing the function to omit
that would require changing to remove the unwanted +/-.

HTML 5 deviates from ISO8601, in that it allows the year to be any
number of characters greater than 4, and not only allows omission of the
+/- for the extended range, but actually forbids it.
http://www.whatwg.org/specs/web-app...on-microsyntaxes.html#parse-a-month-component

A valid ISO8601 string +20000-12-12 is not valid in HTML 5, yet an
non-ISO8601 string 20000-12-12 is valid for HTML 5.

This deviation is used for input type="date"
http://www.whatwg.org/specs/web-app.../states-of-the-type-attribute.html#date-state

Opera seems to recognize only 1582-9999. For example:

<input type="date" value="1500-12-12">

- populates the picker with year 1582, yet the input's value reads
1500-12-12 and valueAsDate.toString() results "Tue Dec 11 1500 16:00:00
GMT-0800".

Seems to be a limitation with the picker, not the input.

value="0909-08-31" results in the INPUT value appearing as "909", the
datepicker displaying 1582, and valueAsDate being null.

This seems like a misimplementation of the HTML 5 datepicker.

AFAIK, no CSS hooks exist for styling date picker, such as "selected
date" or "today".
Reverting to the first article of the thread : the comment says what
happens if the string dies not match the format YYYY-MM-DD, but it does
not actually say what happens if the digits supplied are incompatible
with the Gregorian Calendar. At least, change the line to

if (month != date.getMonth() + 1) { // validate numerical values

Goodman, Flanagan, ISO/IEC 16262, ECMA 262 FD5, Asen Bozhilov, the
recently-disparaged old Netscape MAN-type page (generally), even
<http://www.nasa.gov/js/195153main_countdownclock.js> - they all put a
space between "if" & "("; the FAQ should do so likewise. It improves
legibility.
Yes, I know, you brought this up before.

Crockford does it, too. It isn't my style, but if enough others agree, I
can change the FAQ.
 
G

Garrett Smith

Dr said:
In comp.lang.javascript message <[email protected]
september.org>, Mon, 19 Oct 2009 17:33:29, Garrett Smith


It is not the business of a general purpose date-output routine, as this
should be, to pay much heed to the various preferences of petty bodies
or specialised systems. It should heed, but need not be absolutely
bound by, ISO 8601. And it should either support, or be readily
adaptable to support, field orders other than Y M D, since those may be
required for display.

Its prime purpose should be to support (proleptic Gregorian) YYYY-MM-DD
for current years; all years in 1000-9999 are equally easy.

Except dates before year 1582 is a problem, as with input type="date" in
Opera 10.
It should also support earlier years, 0-999, in 4-digit form. That
reduces confusion between years (for example) 98 & 1998, 10 & 2010 - and
those may unintentionally occur in Objects.

Of course; YYYY.
And it should never, for any value that a Date object can (rightly or)
contain, give a string which actually represents a non-corresponding
year.
That would be a bug.
It should, therefore, give, as well as the obvious MM & DD, Math.abs of
the year, toString-ed and with leading zeroes added to bring the number
of digits, if fewer, up to four. And in front of that, it should put a
representation of sign : "-" for negative years, and a user-chosen one
of "+", " ", "", for non-negative years.
Why Math.abs? The year is checked to be in range.

You think that should be removed. But Math.abs? That would convert a
negative year to a positive one. That sounds like the bug you described
two paragraphs up.

The range-checking was the only way to define the |dateInRange|
parameter.

It sounds like you are suggesting that the range be unlimited. But
obviously there must be *some* limit on years.
It can be described as compliant with ISO 8601 for 0000-9999 (with sign
""), with XML for 0001-9999, etc.

The range we agreed on previously.
In most applications, which means at least business and ordinary
leisure, there is no need to make allowance for years outside 1000 to
9999. Therefore, the code for those extremes should be easily
removable. There is no need to test the year-range within the routine;
that is the business of the application.
There is no application here.
Hoteliers, for example, do not generally accept bookings for dates
before the present day; undertakers (morticians) are commonly reluctant
to consider dates of death after the present day.
Makes sense. The relevant point I take is that we can imagine situations
that are likely to be common and write a function that fulfills those
cases.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Except dates before year 1582 is a problem, as with input type="date" in
Opera 10.

But type="date" would be a proprietary extension in a not properly tested
new version of a not widely distributed closed-source browser.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Tue, 20 Oct 2009 12:18:41, Garrett Smith
Where is the ISO 8601:1998 Draft Revision that XML Schema bases this
claim on? DThe official version of ISO8601:1998 does not support that
claim. ISO8601:2000 contradicts it.

Copies of older 8601 are linked in <http://www.qsl.net/g1smd/isopdf.htm>
which is readily found with Google.

A link for a legitimate free copy of the current (2004) version would be
welcome; the one I had has been changed.
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Tue, 20 Oct 2009 14:16:28, Garrett Smith
How does the code look? Seems to be fine, based on feedback so far.

Read what I wrote. I don't doubt that it does what you intended.
It is shorter and faster than the previous version.


isInRange is more descriptive.

But, in the context, greater descriptiveness is surplusage which should
be eschewed. Longer variables are more effort to read, and should only
be used where necessary.

You brought this up before. "throw" is a flow of control statement,
(like if, else, etc). The FAQ does not explain those.

Yes. But a knowledge of English is sufficient to understand those; and,
where they are used in the FAQ one can see the whole structure.

One who codes 'throw' needs to know what happens to the throw of control
(i.e. does the next statement get executed) and what the consequences of
throw are. It would be much better to use an alert there and/or to
return a mildly abusive string; and to have throw and its associates
properly covered by a FAQ section.


I need a Huffman-coded keyboard so that hitting
an adjacent key bever gives a valid word.

Is it? I didn't notice a difference in speed.

Yes it is; that's why I wrote that it is. I measured it. From memory
and from the wording I chose, the proportional gain in speed is more
than that of shortness, but not greatly so.

Abbreviated function name in constant case. We're not doing that.

Well, you can write a longer name, but it clutters the code.
Any date? I recall previously you thought capping at 9999 was sufficient
for most cases (and that was agreed on).

For most cases; but a FAQ routine should be general.
±YYYYY-MM-DD is not large enough for Astronomy, or other sciences.

That's 5 'Y's. YYYY is adequate for all dateable actual events.
Cosmology needs to reach (IIRC) years -1.5E10 to +1E35 and higher, but
needs no calendar dates.

One could write a Cosmological Date Object, holding its data in
two fields : one a Date Object with values in years 2000..2399
or 10000-10399 and the other a Number of integer value (or a
hidden Int64) giving the multiple of 400 years to be added.

Years 0-9999 represent a widely recognized range and fit the most common
ISO8601 format (poor XML Schema deviates with year 0).

Expanded range requires a +/- char. It is less portable to exchange
formats that do not recognize that format. Changing the function to omit
that would require changing to remove the unwanted +/-.

One should take 8601 into consideration, but one is not obliged to
conform in all detail. It would be foolish, for example, to put a +
sign on Actual Dates of Easter Sunday, since they are necessarily
greater than about Year 30. AISB, the positive indicator should be a
choice of "+" " " & "".

HTML 5 deviates from ISO8601, in that it allows the year to be any
number of characters greater than 4, and not only allows omission of the
+/- for the extended range, but actually forbids it.
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-
microsyntaxes.html#parse-a-month-component

A valid ISO8601 string +20000-12-12 is not valid in HTML 5, yet an
non-ISO8601 string 20000-12-12 is valid for HTML 5.

It is naive, alas, to expect a single format to be compatible with all
applicable standards, especially for values requiting formats outside
the commonly-used range.
This deviation is used for input type="date"
http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-
the-type-attribute.html#date-state

Opera seems to recognize only 1582-9999. For example:

<input type="date" value="1500-12-12">

I've not come across that type. Have you a good link? It's not
JavaScript; but it's close.

It's careless to cut off at 1582-01-01 rather than 1582-10-15 or at
least 1582-10.

It seems not a very useful cross-browser control.

Yes, I know, you brought this up before.

Crockford does it, too. It isn't my style, but if enough others agree, I
can change the FAQ.


Please cut out what you are not commenting on (FAQ 1.3 B 1) and preserve
quoted paragraph spacing (").
 
G

Garrett Smith

Dr said:
In comp.lang.javascript message <[email protected]
september.org>, Tue, 20 Oct 2009 12:18:41, Garrett Smith


Copies of older 8601 are linked in <http://www.qsl.net/g1smd/isopdf.htm>
which is readily found with Google.
Thanks.

http://www.mail-archive.com/[email protected]/msg00085/8601v04.pdf

1998 Draft, second edition.

| In these expressions the year component may have the value [0000] and
| the month and day-of-the-month components may have the
| value [00]. Truncated representations may only be used if the omitted
| components are zero.

A link for a legitimate free copy of the current (2004) version would be
welcome; the one I had has been changed.
I see the FAQ has changed the link to require authentication:
http://isotc.iso.org/livelink/livelink/4021199/ISO_8601_2004_E.zip?func=doc.Fetch&nodeid=4021199

The page that the request is redirected to does not state how to get a
username and password.

It might be well enough to host ISO8601 on merlyn or jibbering.

Can you spare the bandwidth?

I can't very well host anything on dhtmlkitchen. Unstable host.

My host changed servers and reconfigured the JVM, and something
(probably the blog) eats up too much CPU, No idea how they configured
the garbage collection; they won't tell, but it slowed the site to about
6s latency, per jsp, and then they shut it down. This happened right
arter their server migration.

So, not an option.
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Wed, 21 Oct 2009 00:56:28, Garrett Smith
Except dates before year 1582 is a problem, as with input type="date" in
Opera 10.

JavaScript uses proleptic Gregorian, with astronomers' year numbers.
Neither 1582 not 1752 is special. Perhaps you should have set the value
of attribute min, having first chosen a browser in which it works.

Type=date in Opera 9.64 would be better if the date digits were
readable. Types week & month in 9.64 don't onChange. I've started
testing those in <js-date3.htm#HTML>


Of course; YYYY.

Yes, easy enough, but NOT "equally easy". You answer without
understanding, or remembering, what you should have read.

That would be a bug.

Why Math.abs? The year is checked to be in range.

I am referring to what a general date-to-string routine needs to do; not
to what you have coded.
You think that should be removed. But Math.abs? That would convert a
negative year to a positive one. That sounds like the bug you described
two paragraphs up.

You have failed to read all that you quoted above. Math.abs AND sign.
The range-checking was the only way to define the |dateInRange|
parameter.

It sounds like you are suggesting that the range be unlimited. But
obviously there must be *some* limit on years.

There is no need to impose one. a compliant Date Object goes 1E8 days
from 1970.0 GMT; about +-275000 years. At least one browser can be
pushed further. A general routine should handle all years that
getFullYear can return. That means the full IEEE Double range, allowing
for browser internal non-compliance. There is no need to put any lesser
limit inside.

The range we agreed on previously.

I mean that said description should be GIVEN in such terms.
There is no application here.

Which is precisely why the routine should be general, and the imposing
of application-dependent limits left to the user's wrappers.

Note that, within a single page set, different dates have different
limits of validity. Maternity hospital inbound patients can have date
of birth flagged as improbable if less than 13 years old; those DoBs are
the same when those patients leave, but other patients are expected to
have a rather recent DoB. Different parts of an application can have
different limits.

It's not as if there was any difficulty in handling any IEEE Double
integer (with one exception) for Year; Math.abs, toString, pad to 4
characters if less, prepend sign as '-' if negative and one of '' ' '
'+' if positive. Something like (untested here) :-

Y = D.getFullYear()
S = Sign(Y) // supplied function
Y = Math.abs(Y).toString()
while (Y.length<4) Y = "0"+Y
return S + Y + "-" ...



Makes sense. The relevant point I take is that we can imagine
situations
that are likely to be common and write a function that fulfills those
cases.

NO NO NO. That's how getYear came to be what it is; OK in 1900-1999,
but varying outside that. See the top of
<http://www.koreaherald.co.kr/world/herald.asp> in various browsers
including Firefox.

A FAQ should give something as general as practicable; readers can much
more easily remove what they do not need than they can add extras.
 
T

Thomas 'PointedEars' Lahn

Dr said:
Thomas 'PointedEars' Lahn posted:

But see <http://dev.w3.org/html5/markup/input.date.html>.
W3 seem to think that 'type="date"' is in HTML 5.

They don't.
Perhaps they are better informed than you are.

Perhaps you don't know which relevance a W3C Working Draft has with regard
to Web standards, especially this controversial one developed (primarily)
by WHATWG, not W3C. You could read the draft's "Status of this document"
section to get yourself informed.


PointedEars
 
G

Garrett Smith

Thomas said:
But type="date" would be a proprietary extension in a not properly tested
new version of a not widely distributed closed-source browser.
A strategy can be used to feature-test input type="date" and, where not
supported, a js-driven calendar used.

The feature test:

var inputTypeDate = document.createElement("input");
inputTypeDate.setAttribute("type", "date");
var IS_NATIVE = /date/i.test(inputTypeDate.type)
inputTypeDate = null;

A problem with that strategy I see is that Opera's datepicker does not
display year before 1582.

HTML 5 parse a month algorithm deviates from ISO8601, allowing year to
be infinitely large, in common era only, and with no sign. That could be
an interop issue where the native control would allow: YYYYYYYY-MM-DD,
but the js-calendar recognizes only YYYY, with:
/(?:^|\s+)(\d{4})-(\d\d)-(\d\d)(?:$|\s+)/

I think that year can be enforced by the HTML 5 "max"
attribute/property, but then there is consideration for if the widget
should use min/max attributes.

http://github.com/GarrettS/ape-javascript-library/blob/master/src/widget/calendar/Calendar.js
My site is down, due to server/host issue, so an example can not be
easily examined, but one can view the source, and even use gitHubSource
bookmarklet:

Source:
http://github.com/GarrettS/ape-java...example/widget/calendar/index.html#gTestFrame

gitHubSource bookmarklet:

// Seems to work for some HTML documents I've tried on github.
function gitHubSource() {
var ID = "gTestFrame",
node = document.getElementById(ID);
if (node) {
node.parentNode.removeChild(node);
}
var code = document.getElementById("LC1").parentNode;
code = code.cloneNode(true);
var divs = code.getElementsByTagName("div");
var tn = document.createTextNode(" \n");
for (var i = 0; i < divs.length; i++) {
code.insertBefore(tn.cloneNode(false), divs);
}
code = code.textContent || code.innerText;
var s = location.pathname,
lastPath = /\/[^\/]+$/,
relUrlAttr = /((href|src)=['|"])(?:\.)/;
s = s.replace("blob/", "raw/");
s = s.replace(lastPath, "/") + ".";
j = 0;
while (relUrlAttr.test(code)) {
code = code.replace(relUrlAttr, RegExp.$1 + s);
}
var iframe = document.createElement("iframe");
iframe.setAttribute(
"style", "width: 90%; height: 300px; margin-bottom: 4px");
iframe.id = ID;
iframe.src = "about:blank";
document.body.appendChild(iframe);
var win = iframe.contentWindow;
win.document.write(code);
win.document.close();
iframe.focus();
location.hash = "#" + iframe.id;
}
gitHubSource();
 
G

Garrett Smith

Dr said:
In comp.lang.javascript message <[email protected]
september.org>, Wed, 21 Oct 2009 00:56:28, Garrett Smith


JavaScript uses proleptic Gregorian, with astronomers' year numbers.
Neither 1582 not 1752 is special. Perhaps you should have set the value
of attribute min, having first chosen a browser in which it works.

Type=date in Opera 9.64 would be better if the date digits were
readable. Types week & month in 9.64 don't onChange. I've started
testing those in <js-date3.htm#HTML>




Yes, easy enough, but NOT "equally easy". You answer without
understanding, or remembering, what you should have read.



I am referring to what a general date-to-string routine needs to do; not
to what you have coded.


You have failed to read all that you quoted above. Math.abs AND sign.


There is no need to impose one. a compliant Date Object goes 1E8 days
from 1970.0 GMT; about +-275000 years. At least one browser can be
pushed further. A general routine should handle all years that
getFullYear can return. That means the full IEEE Double range, allowing
for browser internal non-compliance. There is no need to put any lesser
limit inside.



I mean that said description should be GIVEN in such terms.


Which is precisely why the routine should be general, and the imposing
of application-dependent limits left to the user's wrappers.

Note that, within a single page set, different dates have different
limits of validity. Maternity hospital inbound patients can have date
of birth flagged as improbable if less than 13 years old; those DoBs are
the same when those patients leave, but other patients are expected to
have a rather recent DoB. Different parts of an application can have
different limits.

It's not as if there was any difficulty in handling any IEEE Double
integer (with one exception) for Year; Math.abs, toString, pad to 4
characters if less, prepend sign as '-' if negative and one of '' ' '
'+' if positive. Something like (untested here) :-

Y = D.getFullYear()
S = Sign(Y) // supplied function
Y = Math.abs(Y).toString()
while (Y.length<4) Y = "0"+Y
return S + Y + "-" ...

The +/- sign should not be present when year is 0-9999.

When year is < 0, but > -9999, the sign, plus a leading 0, are
necessary.

-9999-12-12 - INVALID.
-09999-12-12 - VALID.
NO NO NO. That's how getYear came to be what it is; OK in 1900-1999,
but varying outside that. See the top of
<http://www.koreaherald.co.kr/world/herald.asp> in various browsers
including Firefox.

I see articles. Enabling script for that domain..

After enabling javascript, I see:
Wednesday, October 21, 109

I see your point.
A FAQ should give something as general as practicable; readers can much
more easily remove what they do not need than they can add extras.
This requires rewriting the entire date section, starting with the main
section, which states:

| The ISO Extended format for common date is YYYY-MM-DD, and for time is
| hh:mm:ss.

I do not have a draft for how to explain your proposed format.

That format is used in the two answers in that section.

I see your point in this. Valid, but the tradeoff is introducing more
complexity WRT explaining ISO8601, in a javascript FAQ.
 
G

Garrett Smith

Garrett said:
The +/- sign should not be present when year is 0-9999.

When year is < 0, but > -9999, the sign, plus a leading 0, are
necessary.

Correction: should be:
When year is < 0, but >= -9999, the sign, plus enough leading zeros, to
fit a pattern YYYYY should be used.

The sign is apparently not necessary. I had believed that it was
necessary for expanded representation, but apparently that was
incorrect, as I cannot find that in the specification.

Expanded Representation:
| If, by agreement, expanded representations are used, the formats shall
| be as specified below. The interchange parties shall agree the
| additional number of digits in the time element year. In the examples
| below it has been agreed to expand the time element year with two
| digits.
| [example]

The example uses the sign for year, but apparently that may be omitted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,084
Messages
2,570,596
Members
47,217
Latest member
GuadalupeE

Latest Threads

Top