2016-07-22 9 views
2

Dateプロトタイプのいくつかの拡張機能を使用して、いくつかの操作を実行しています(アドバイス:それは実行しないでください、現在のプロジェクトでは遅すぎます)。いつもよりもいくつか問題がある。 H内の文字列を解析するためにJavaScriptが正しく解析されない

:m書式、私はカスタム関数を作り、このような日付のプロトタイプにそれを割り当てられて:あなたは日付オブジェクトをログに記録しようとしたが、最近まで働いたときに

Date.__parse = Date.parse; 

Date.parse = function(string){ 
    var pattern = /^\d{1,2}:\d{1,2}/ig; 

    var today = new Date(); 

    if (pattern.exec(string)){ 
     var year = today.getFullYear(); 
     var month = today.getMonth()+1; 
     var day = today.getDate(); 

     var t = year+"-"+month+"-"+day+" "+string; 
     var timestamp = Date.__parse(t); 

     return new Date(timestamp); 
    } 
    else{ 
     return new Date(Date.__parse(string)); 
    } 
} 

醜いです。

Date.parseは「d-m-Y」形式の日付で動作するようですが、最近は「無効な日付」を返しています。

メジャーなブラウザが日付を解析する方法や仕様が変更される方法に何か変わったのですか、以前にエラーがあったと仮定しなければならなかったのですが、運が良かったため "無効な日付" (私は主に入力フィールドを検証するために関数を使用しているので、気付かないうちに非常にうまく通過する可能性があります)。

私は自分の日付スクリプトを書いて、js Dateオブジェクトを完全に忘れてしまいます。本当に恐ろしいです(moment.jsを使用しようとしましたが、私が使っているコンポーネントのパフォーマンスは非常に悪く、なぜ私はカスタム機能を作らなければならなかったのですか)。

より良く理解するためにEDIT

。私がやっていたもの

が動作するように見えた:私は、検証エラーを追跡した後に見つけたもの

Date.parse("23-7-2016") // Never got an error, expected 23 Jul 2016 

var startDate = Date.parse("23-7-2016"); 
console.log(startDate.toISOString()); //Got Invalid Date 

私が起こっているかもしれないと思う何

var startDate = Date.parse("12-7-2016"); 
// expected 12 Jul 2016, got 7 Dec 2016, silently fails, everyone is happy 

なぜ私は前のことだと思います。ケースはそうではありません:私はインタラクティブなスケジューラを使用し、何千ものテストを実行しましたが、このようなエラーはほとんど気付かれませんでした。

最悪のシナリオ:クロムが更新され、日付の解析方法が変更されました。

わからない...誰かが私を啓発できることを望みました。

+0

あなたがして、この機能を提供するためのいくつかの値の入力例を与えることができますか?また、一般的な質問 - なぜあなたは文字列に日付を変換するのですか?それはあなたが何らかの外部ソースから文字列として日付を取得したか、またはクライアントとサーバー間の通信のためにそれを行うためですか? –

+0

私はpattern.execの代わりにあなたの例に基づいてpattern.testを使うべきだと思います。 –

+0

申し訳ありませんが、例が広すぎます。私がそれを行う主な用途は、月間カレンダー、週スケジュール、または毎日のスケジュールとして表示されるイベントスケジューラーです。たとえば、週単位のビューでは、イベントをフックして後で描画するために、私はweekDaysを過ぎてから何時間も繰り返す必要があります。機能の一部はイベントを追加することで、日付を反復するときに、それらを読み込み可能なローカライズされた文字列に変換する必要があります(私はテキストパーサー全体をポストしません)。 1日をクリックすると、日付の値を保存する必要があります。 – sergio0983

答えて

1

私はあなたのメソッドが有効な入力に対して有効であると判断しました。あなたの正規表現は23時間以上59分以上有効です。

すべての有効な入力を列挙するjsfiddleを参照してください。 https://jsfiddle.net/kLngLL72/4/

私の例では、関数の無限のネスティングを防ぐために、Date.parse関数を上書きしませんでした。

Date.__parse = Date.parse; 

var dparse = function(string){ 
    var pattern = /^\d{1,2}:\d{1,2}/ig; 

    var today = new Date(); 

    if (pattern.exec(string)){ 
     var year = today.getFullYear(); 
     var month = today.getMonth()+1; 
     var day = today.getDate(); 

     var t = year+"-"+month+"-"+day+" "+string; 
     var timestamp = Date.__parse(t); 

     return new Date(timestamp); 
    } 
    else{ 
     return new Date(Date.__parse(string)); 
    } 
} 

$("#data").append("<tr><td>" + dparse("01-01-2016 1:31") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("1-1-2016 0:0") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("1-1-2016 12:59") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("1-1-2016 23:59") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("12-31-2016 1:1") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("12-31-2016") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("12-31-2016 24:0") + "</td></tr>"); 
$("#data").append("<tr><td>" + dparse("12-31-2016 99:99") + "</td></tr>"); 

for (var i = 0; i < 24; i++) 
{ 
    for (var j = 0; j < 60; j++) 
    { 
    $("#data").append("<tr><td>" + dparse("12-31-2016 " + i + ":" + j) + "</td></tr>"); 
    } 
} 
UPDATED

- NEW JS FIDDLE https://jsfiddle.net/mfe55xun/2/ この新しい例、だけで時間と分の文字列を渡します。

Date.__parse = Date.parse; 

var dparse = function(string){ 
    var pattern = /^\d{1,2}:\d{1,2}/ig; 

    var today = new Date(); 

    if (pattern.exec(string)){ 
     var year = today.getFullYear(); 
     var month = today.getMonth()+1; 
     var day = today.getDate(); 

     var t = year+"-"+month+"-"+day+" "+string; 
     var timestamp = Date.__parse(t); 

     return new Date(timestamp); 
    } 
    else{ 
     return new Date(Date.__parse(string)); 
    } 
} 

$("#data").append("<tr><td>" + dparse("99:99") + "</td></tr>"); 

for (var i = 0; i < 24; i++) 
{ 
    for (var j = 0; j < 60; j++) 
    { 
    $("#data").append("<tr><td>" + dparse(i + ":" + j) + "</td></tr>"); 
    } 
} 

UPDATE

あなたの入力文字列が日付が含まれている場合、通常のDate.parseはあなたのHで文字列に働くだろうことに留意すべきである:メートルの書式:

Date.parse("1/2/2016 4:3") 

現在の日付文字列に "4:3"を追加するだけで、カスタムDate.parse関数を削除することができます。

更新質問

のための別のアップデート私はフォーマットが今まであなたのために正しく働いたことはないと思います。それはうまくいく場合がありますが、いつも "23rd"を1ヶ月と解釈し、無効な日付を与えます。この形式の考えられるすべての日付をループして、1〜12日の作業だけを通知する別のjsfiddleの例を示します。 https://jsfiddle.net/mfe55xun/6/

Date.__parse = Date.parse; 

var dparse = function(string){ 
    var pattern = /^\d{1,2}:\d{1,2}/ig; 

    var today = new Date(); 

    if (pattern.exec(string)){ 
     var year = today.getFullYear(); 
     var month = today.getMonth()+1; 
     var day = today.getDate(); 

     var t = year+"-"+month+"-"+day+" "+string; 
     var timestamp = Date.__parse(t); 

     return new Date(timestamp); 
    } 
    else{ 
     return new Date(Date.__parse(string)); 
    } 
} 

for (var i = 0; i <= 31; i++) 
{ 
    for (var j = 0; j <= 12; j++) 
    { 
    $("#data").append("<tr><td>" + i + "-" + j + "-2016 = " + dparse(i + "-" + j + "-2016") + "</td></tr>"); 
    } 
} 

結果ループを見てみましょう。

test results 

0-0-2016 = Invalid Date 
0-1-2016 = Invalid Date 
0-2-2016 = Invalid Date 
0-3-2016 = Invalid Date 
0-4-2016 = Invalid Date 
0-5-2016 = Invalid Date 
0-6-2016 = Invalid Date 
0-7-2016 = Invalid Date 
0-8-2016 = Invalid Date 
0-9-2016 = Invalid Date 
0-10-2016 = Invalid Date 
0-11-2016 = Invalid Date 
0-12-2016 = Invalid Date 
1-0-2016 = Invalid Date 
1-1-2016 = Fri Jan 01 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-2-2016 = Sat Jan 02 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-3-2016 = Sun Jan 03 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-4-2016 = Mon Jan 04 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-5-2016 = Tue Jan 05 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-6-2016 = Wed Jan 06 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-7-2016 = Thu Jan 07 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-8-2016 = Fri Jan 08 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-9-2016 = Sat Jan 09 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-10-2016 = Sun Jan 10 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-11-2016 = Mon Jan 11 2016 00:00:00 GMT-0500 (Eastern Standard Time) 
1-12-2016 = Tue Jan 12 2016 00:00:00 GMT-0500 (Eastern Standard Time) 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC or NaN if the string is unrecognised or, in some cases, contains illegal date values (e.g. 2015-02-31).

It is not recommended to use Date.parse as until ES5, parsing of strings was entirely implementation dependent. There are still many differences in how different hosts parse date strings, therefore date strings should be manually parsed (a library can help if many different formats are to be accommodated).

+0

素晴らしい例ですが、時間や分が問題を引き起こしていないことは間違いありません。それらの入力値はドロップダウンから来て、間違った値を送ることはできません。また、表示された値は、あなたが書いたもののようなイテレータから来ています。とにかく、あなたが示唆したように、すべての日付解析の内容を変更する予定です.Dateオブジェクトを変更することは本当に悪い考えです。 – sergio0983

関連する問題