2

私は JavaScript の専門家ではないため、過度の単純化がどのように間違っているかを修正または説明してください。

しかし、オブジェクトが有効な日付であるかどうかを知る必要があるだけです。これは、ユーザー入力 (つまり、テキスト ボックス) からのみ取得されます。

var is_valid_date = function(date) {
    try {
        var d = new Date(date);
        return true;
    }
    catch(e) {
        return false;
    }
}
4

3 に答える 3

12

受け入れたい日付の形式を決定する必要があります。

次に、どのフォームを受け入れたいかがわかったら、MDN の仕様new Date(str)またはdate.parse() MDNで仕様を確認し、必要なものを正確にサポートしているかどうか、およびエラー状態で正しいことを行うかどうかを確認できます (おそらくそうではないでしょう)。そうでない場合は、手動で解析する必要があります。

さらにサポートが必要な場合は、受け入れたい日付の形式を指定する必要があります。

また、JavaScript が追加の日付形式をサポートするように移動したため、ブラウザーの違いもいくつかあります。また、以前のブラウザーではそれらの間にいくつかの矛盾がありました。つまり、合法および違法な日付形式文字列を使用して簡単なテスト スクリプトを自分で作成し、妥当性検出は、いくつかのブラウザーで必要なことを行います。これは、正しく理解するための高度な科学ではありませんが、簡単なことでもなく、元の日付オブジェクトがサポートしているものだけを受け入れたい場合を除いて、いくつかの作業が必要です (これはありそうもないことです)。

これが私のコードである場合、すべてのブラウザーで 100% 確実に機能することがわかっている入力形式を手動で解析することは、独自の手動解析であるため、はるかに少ない作業であると判断するでしょう。おそらく、正規表現を使用して日付を解析し、各コンポーネントを数値に変換して、各コンポーネントの有効性を確認します。次に、これらの数値コンポーネントを Date コンストラクターにフィードして、Date オブジェクトを作成できます。

組み込みの日付クラスは、ユーザー入力にはあまり役に立ちません。これにライブラリを使用する場合、date.js ライブラリには、この点で便利な機能がたくさんあります。

これらの米国形式を受け入れる手動解析関数の例を次に示します。

mm-dd-yyyy
mm dd yyyy
mm/dd/yyyy

JS コード:

function checkDate(str) {
    var matches = str.match(/(\d{1,2})[- \/](\d{1,2})[- \/](\d{4})/);
    if (!matches) return;

    // parse each piece and see if it makes a valid date object
    var month = parseInt(matches[1], 10);
    var day = parseInt(matches[2], 10);
    var year = parseInt(matches[3], 10);
    var date = new Date(year, month - 1, day);
    if (!date || !date.getTime()) return;

    // make sure we have no funny rollovers that the date object sometimes accepts
    // month > 12, day > what's allowed for the month
    if (date.getMonth() + 1 != month ||
        date.getFullYear() != year ||
        date.getDate() != day) {
            return;
        }
    return(date);
}

そして、いくつかのテストケースを含むデモ: http://jsfiddle.net/jfriend00/xZmBY/

ユーロ形式が必要な場合は、コードをそれに切り替えるのは簡単なことです。どちらの場合でも、受け入れる形式を決定し、それをコーディングしてから、どの形式が必要かをユーザーに伝える必要があります。これが厄介だと思われる場合は、多くのサイトがこの複雑さを持たない日付カレンダー ピッカーを使用している理由がわかるでしょう。

于 2012-04-21T21:43:51.013 に答える
1

私は JavaScript の専門家ではないため、過度の単純化がどのように間違っているかを修正または説明してください。

しかし、オブジェクトが有効な日付であるかどうかを知る必要があるだけです。これは、ユーザー入力 (つまり、テキスト ボックス) からのみ取得されます。

単純化しすぎた理由はここにあります。

まず第一に、Date オブジェクトの文字列表現の有効性を本当にチェックしたいようです。スクリプト内の何かに日付を使用したり、サーバーに送信したりしたいので、これだけでは特に役に立ちません。

スクリプトで日付を使用する場合は、注意事項があります。

new Date('2020-10-10') // Fri Oct 09 2020 20:00:00 GMT-0400 (EDT)

サーバーに渡す場合は、有効性を確認するだけでなく、サーバー側のコードが解釈できる形式を使用する必要があります。

その場合は、文字列を選択した形式に正規化することを検討できます。クライアント側とサーバー側の両方のコードで、正規化された文字列から同等の日付を作成できるようにしたいと考えています。簡単にするために、形式は (タイムスタンプではなく) 人間が判読できる形式にすることができ、テキスト入力の値を正規化された文字列に置き換えることができます。

文字列の有効性を確認することは、単に正規化の一部である可能性があります...false入力が間違っている場合は関数を返すか、空の文字列を返し、テキスト入力の値を変更せず、代わりに値が無効であることを示すメッセージを表示します:

// assume `birthday` is a text input.

birthday.onblur = function() {
    
    var dateString = normalizeDate(birthday.value);
    
    if (dateString) {
        validator.style.display = 'none';
        birthday.value = dateString;
    } else {
        validator.style.display = 'block';
    }
        
}; 

normalizeDate関数がどのように見えるかの例を次に示します。この例では「yyyy-mm-dd」という形式を使用していますが、必要に応じて変更できます。

function normalizeDate(dateString) {

    // If it's not at least 6 characters long (8/8/88), give up.
    if (dateString.length && dateString.length < 6) {
        return '';
    }

    var date = new Date(dateString), 
        month, day;

    // If input format was in UTC time, adjust it to local.
    if (date.getHours() || date.getMinutes()) {
        date.setMinutes(date.getTimezoneOffset());
    }
    
    month = date.getMonth() + 1;
    day = date.getDate();
    
    // Return empty string for invalid dates
    if (!day) {
        return '';
    }
    
    // Return the normalized string.
    return date.getFullYear() + '-' +
        (month > 9 ? '' : '0') + month + '-' + 
        (day > 9 ? '' : '0') + day;
}

これが必須のライブデモです。

于 2012-04-22T21:09:10.527 に答える
0

new Date()たとえば、 month>12 の場合は例外をスローしませんDate.parse()。戻り値を使用してテストできますisNaN()

于 2012-04-21T21:28:06.527 に答える