Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normative: Specify Date string conversion functions #848

Merged
merged 7 commits into from
May 30, 2017

Conversation

littledan
Copy link
Member

Implementations seem to agree on semantics here for the most
part, modulo timezone strings, which are left implementation-defined.

Addresses part of #845

@domenic domenic added the needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 label Mar 17, 2017
spec.html Outdated
<!-- es6num="20.3.4.41.1" -->
<emu-clause id="sec-todatestring" aoid="ToDateString">
<h1>Runtime Semantics: ToDateString( _tv_ )</h1>
<p>The following steps are performed:</p>
<emu-alg>
1. Assert: Type(_tv_) is Number.
1. If _tv_ is *NaN*, return `"Invalid Date"`.
1. Return an implementation-dependent String value that represents _tv_ as a date and time in the current time zone using a convenient, human-readable form.
1. Let _t_ be LocalTime(_tv_).
1. Return the String value formed by concatenating DateString(_t_), `" "`, and TimeString(_t_), TimeZoneString(_tv_).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... `" "`, TimeString(_t_), and TimeZoneString(_tv_). (the word and is misplaced)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks

@littledan
Copy link
Member Author

@domenic Do you have good suggestions for how to write tests here? I'm not sure how to do it in a way that will work in all time zones. (test262 has repeatedly had issues where tests were broken in certain timezones.)

spec.html Outdated
<emu-alg>
1. Assert: Type(_tv_) is Number.
1. Assert: _tv_ is not *NaN*.
1. Return String value formed by concatenating _result_, ToString(HourFromTime(_tv_)), `":"`, ToString(MinFromTime(_tv_)), `":"`, ToString(SecFromTime(_tv_)) and `" GMT"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete extraneous result variable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

spec.html Outdated
1. Let _offset_ be (LocalTZA + DaylightSavingTA(_tv_)) / msPerSecond.
1. Assert: _offset_ is an integer, and -100000 &lt; _offset_ &lt; 100000.
1. If _offset_ &ge; 0, let _offsetSign_ be `"+"`; otherwise, let _offsetSign_ be `"-"`.
1. Let _offsetString_ be abs(_offset_) formatted as a four-digit number, padded to the left with zeros if necessary.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The offset needs to be formatted as HHMM, not as SSSS. The four preceding steps (starting with Let _offset_) should be replaced with:

  1. Let offset be LocalTZA + DaylightSavingTA(tv) /* (NB: value in milliseconds) */
  2. If offset ≥ 0, let offsetSign be "+"; otherwise, let offsetSign be "-".
  3. Let offsetMin be the String representation of MinFromTime(abs(offset)), formatted as a two-digit number, padded to the left with a zero if necessary.
  4. Let offsetHour be the String representation of HourFromTime(abs(offset)), formatted as a two-digit number, padded to the left with a zero if necessary.

And the last step of the algorithm, below:

  1. Let offsetString be the concatenation of offsetSign, offsetHour, offsetMin, and tzName.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, of course! Uploaded a new version to use your text.

@domenic
Copy link
Member

domenic commented Mar 18, 2017

Do you have good suggestions for how to write tests here? I'm not sure how to do it in a way that will work in all time zones. (test262 has repeatedly had issues where tests were broken in certain timezones.)

Well, you can certainly test the Invalid Date cases.

You should be able to run regexps to make sure the patterns are met for all methods, including the time zone format restriction.

You should be able to test .toUTCString() exactly on its entire range of inputs, including extreme ones like 0, +/- Infinity, Number.(MIN/MAX)_SAFE_INTEGER, and Number.(MIN/MAX)_VALUE.

You should be able to pick times in the middle of a given month so that timezone changes can't change the month string, thus allowing you to test the month name mapping even for toString().

You might be able to pick times such that in every timezone they fall on the same day of the week, thus allowing testing the week day mapping for toString(), but I am not sure.

spec.html Outdated
1. Let _O_ be this Date object.
1. Let _tv_ be ? thisTimeValue(_O_).
1. If _tv_ is *NaN*, return `"Invalid Date"`.
1. Return the String value formed by concatenating DateString(_tv_), `" "`, and TimeString(_tv_).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also here

<!-- es6num="20.3.4.41.1" -->
<emu-clause id="sec-todatestring" aoid="ToDateString">
<h1>Runtime Semantics: ToDateString( _tv_ )</h1>
<p>The following steps are performed:</p>
<emu-alg>
1. Assert: Type(_tv_) is Number.
1. If _tv_ is *NaN*, return `"Invalid Date"`.
1. Return an implementation-dependent String value that represents _tv_ as a date and time in the current time zone using a convenient, human-readable form.
1. Let _t_ be LocalTime(_tv_).
1. Return the String value formed by concatenating DateString(_t_), `" "`, TimeString(_t_), and TimeZoneString(_tv_).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the space, the convention i've seen (and followed in padStart/padEnd) to avoid whitespace ambiguity is " " (a String consisting of 0x0020 SPACE)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bterlson, thoughts on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ljharb I was going to clean this up myself (working on it soon). Planning on replacing all spaces with "the code unit 0x0020 (SPACE)"

spec.html Outdated
1. Assert: _offset_ is an integer, and -100000 &lt; _offset_ &lt; 100000.
1. If _offset_ &ge; 0, let _offsetSign_ be `"+"`; otherwise, let _offsetSign_ be `"-"`.
1. Let _offsetString_ be abs(_offset_) formatted as a four-digit number, padded to the left with zeros if necessary.
1. Let _tzName_ be an implementation-defined string, either `""` or a string of the form `" ("` _name_ `")"` where _name_ is an implementation-defined timezone name.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similarly (and throughout this PR where strings appear), this might want to specify the code units for the space and parens, to avoid ambiguity.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What ambiguity would there be? There are many other places in the spec that use characters with multiple Unicode code points that render similarly or the same (e.g., every a character).

Copy link
Member

@ljharb ljharb Mar 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

¯\_(ツ)_/¯ there are many characters for whitespace. Being precise about the code point ensures no confusion, even with a non-english-centric implementation.

@claudepache
Copy link
Contributor

You might be able to pick times such that in every timezone they fall on the same day of the week, thus allowing testing the week day mapping for toString(), but I am not sure.

You cannot. UTC+14 will always be 1 or 2 days ahead of UTC-12.

Implementations seem to agree on semantics here for the most
part, modulo timezone strings, which are left implementation-defined.

Addresses part of tc39#845
Also fix up the text of DateString().
This actually gets into an area of apparent disagreement between
implementations. For years less than 1000, JSC and SpiderMonkey
implement the specification here, whereas V8 pads to four digits
with spaces, and ChakraCore does not pad the number.
littledan added a commit to littledan/test262 that referenced this pull request Mar 23, 2017
Following the proposed specification in
tc39/ecma262#848
@littledan littledan added needs consensus This needs committee consensus before it can be eligible to be merged. normative change Affects behavior required to correctly evaluate some ECMAScript source text web reality and removed needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 labels Mar 23, 2017
@littledan
Copy link
Member Author

littledan commented Mar 23, 2017

There's a small part of this which actually differs between browsers: When printing the year, if the number is below 1000, JSC and SpiderMonkey pad 0s to the left, V8 pads with spaces, and ChakraCore doesn't pad. This patch goes with the SpiderMonkey/JSC behavior. Before merging it, we should make sure that those engines are OK with the potential compatibility impact of this change.

@ajklein @bterlson What do you think?

@claudepache
Copy link
Contributor

claudepache commented Mar 23, 2017

There's a small part of this which actually differs between browsers: When printing the year, if the number is below 1000, JSC and SpiderMonkey pad 0s to the left, V8 pads with spaces, and ChakraCore doesn't pad.

We should definitely pad with 0s, so that years between 0 and 99 look unambiguous, and we will be able to correct the following glitch of Date.parse() (tested on Firefox, Safari, Chrome and Edge):

var d = new Date;
d.setFullYear(97);
d.toString(); // variation on: Sat Mar 23 0097 16:04:11 GMT+0100 (CET)
var d2 = new Date(Date.parse(d.toString()));
d2.toString(); // variation on: Sun Mar 23 1997 16:04:11 GMT+0100 (CET) //oops, wrong year

spec.html Outdated
<emu-alg>
1. Assert: Type(_tv_) is Number.
1. Assert: _tv_ is not *NaN*.
1. Let _offset_ be (LocalTZA + DaylightSavingTA(_tv_)) / msPerSecond.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be in conflict with #778 that drops DaylightSavingTA(tv) and change LocalTZA to take two params. We have to sort that out somehow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right; this is written against the current spec, but needs to be updated against the other one (based on whichever lands second). I guess rather than LocalTZA, we'd use LocalTimeZoneAdjustment(tz, true), right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. this one was landed first. Then, the other one (#778) has to revise this part as well.

spec.html Outdated
1. Assert: _offset_ is an integer, and -100000 &lt; _offset_ &lt; 100000.
1. If _offset_ &ge; 0, let _offsetSign_ be `"+"`; otherwise, let _offsetSign_ be `"-"`.
1. Let _offsetString_ be abs(_offset_) formatted as a four-digit number, padded to the left with zeros if necessary.
1. Let _tzName_ be an implementation-defined string, either `""` or a string of the form `" ("` _name_ `")"` where _name_ is an implementation-defined timezone name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to give a recommendation while leaving it still up to an implementation about tzName?
If it does, it can be recommended to use the canonicalized timezone in Ecma402. Perhaps, cross-referencing is not a good idea?
Just my 2 cents.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant for this first patch to be purely 100% descriptive. Maybe a change like this could be in a follow-on patch?

As for making that recommendation: I don't know whether we can make it in good faith in the spec yet, as we don't know whether it's web-compatible yet. Maybe the right thing to do would be to try it out in one browser and see if it works. A good thing to know from the committee beforehand would be--would everyone be up for specifying this behavior, assuming it's web-compatible?

Copy link
Contributor

@jungshik jungshik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR ! A couple of comments.

@rwaldron rwaldron added has consensus This has committee consensus. needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 and removed has consensus This has committee consensus. labels May 25, 2017
@rwaldron rwaldron added has consensus This has committee consensus. needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 and removed needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 needs consensus This needs committee consensus before it can be eligible to be merged. labels May 25, 2017
@rwaldron
Copy link
Contributor

Sorry for the label noise.

@littledan littledan removed the needs test262 tests The proposal should specify how to test an implementation. Ideally via github.com/tc39/test262 label May 29, 2017
@littledan
Copy link
Member Author

I previously removed the needs tests label because tests are at tc39/test262#930 (though they need a small fix).

@rwaldron
Copy link
Contributor

@littledan I did a follow up from @leobalter's initial review and merged the test262 PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has consensus This has committee consensus. has test262 tests normative change Affects behavior required to correctly evaluate some ECMAScript source text web reality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants