本編に入る前に、参加者同士でコードを共有・実行できる「同時編集プレイグラウンド(JavaScript版)」が紹介されました。
前回は以下の内容が確認されました。
Date.UTC:数値を返し、引数をUTCとして解釈する。Dateコンストラクタ:Dateオブジェクトを生成し、引数をローカルタイムとして解釈する。Date.prototypeのメソッド:getTime, getDate, setFullYear など。toISOString:ISO 8601拡張形式(年が4桁を超える場合など)への対応。toJSON:意図的にジェネリックに設計されており、thisがDateインスタンスでなくても呼び出し可能。Date.prototype.toLocaleDateString / toLocaleString / toLocaleTimeStringこれらのメソッドは国際化API(ECMA-402)との関連が深く、仕様上は以下のようになっています。
toLocaleDateStringは日付部分、toLocaleTimeStringは時刻部分のみを返すことを目的とする。Date.prototype.toStringこのメソッドは、Date.prototype.toJSONとは異なりジェネリックではありません。
[[DateValue]] を持たないオブジェクトを this として呼び出すと、TypeError を投げます。Dateを継承したクラスのインスタンスは内部スロットを持つため、呼び出し可能です。// 検証コード
const toStr = Date.prototype.toString;
// Dateインスタンスでないオブジェクトからの呼び出しはエラー
try {
toStr.call({});
} catch (e) {
console.log(e); // TypeError: Method Date.prototype.toString called on incompatible receiver
}
// Dateを継承したクラスはOK
class MyDate extends Date {}
console.log(toStr.call(new MyDate())); // 有効な日付文字列が返る
Date.prototype.toString などの裏側で動く、文字列生成のアルゴリズムが詳しく読み解かれました。
ToZeroPaddedDecimalString(n, minLength)数値を指定された長さでゼロ埋めした文字列に変換する共通処理です。
n: 0以上の整数。minLength: 最小の桁数。StringPad 操作(padStartのような処理)が呼ばれます。DateString(tv)Www Mmm dd yyyy(例: Mon Jan 01 2024)という形式の文字列を生成します。
-0001)。TimeString(tv)HH:mm:ss GMT(例: 12:34:56 GMT)という形式を生成します。
HourFromTime, MinFromTime, SecFromTime といった操作を呼び出して各値を抽出します。TimeZoneString(tv)タイムゾーンのオフセットと名前を生成します(例: +0900 (Japan Standard Time))。
+ または -)と4桁の数値(例: 0900)を結合。(JST))の部分は実装依存(implementation-defined)とされており、ブラウザやOSによって異なります。ToDateString(tv)Date.prototype.toString の実体となる操作です。
DateString + space + TimeString + TimeZoneString を結合して返します。Date.prototype.toString() の結果を Date.parse() で再度読み取った場合、ミリ秒単位で値が割り切れない(1000で割り切れない)Dateオブジェクトは、元の値と一致しなくなるという注意点が議論されました。
const d = new Date(1234567890123); // ミリ秒が123
const s = d.toString();
const parsed = Date.parse(s);
console.log(d.getTime() === parsed); // false (ミリ秒が削れるため)
※仕様書のノートには「1000で割り切れる(ミリ秒が0)場合は、パースした結果が一致する」と記載されています。
NaN(Invalid Date)を渡した場合、抽象操作の冒頭でチェックされ、即座に "Invalid Date" という文字列が返ることが確認されました。const d = new Date();
d.setFullYear(-1);
console.log(d.toDateString()); // "Sat Mar 22 -0001" (曜日は計算による)
Date.prototype.toUTCString から読み進める予定。Date オブジェクトの節がまもなく終了し、その次は「Text Processing(文字列処理)」の章に入る見込みです。