69

私はPhonegapベースのiOSアプリに取り組んでいますが、これはすでにAndroid用に行われています。次の行はAndroidでは正常に機能しますが、iOSでは機能しません。なんで?

var d = new Date("2015-12-31 00:00:00");
console.log(d.getDate() + '. ' + d.getMonth() + ' ' + d.getFullYear();

Androidの結果:

31.11 2015

iOSでの結果:

NaN. NaN NaN

違いはどこから来るのですか?

4

7 に答える 7

153

日付文字列が、で機能するように指定された形式ではありませんnew Date。仕様の唯一の形式は、ES5(2009)で追加されたISO-8601の簡略化されたバージョンです。あなたの文字列はその形式ではありませんが、それは本当に近いです。仕様に含まれていないが、広くサポートされている形式に変更するのも簡単です。

あなたのための4つのオプション:

  • 今後のTemporal機能を使用します(現在はステージ3です)
  • 指定された形式
  • ほぼ普遍的にサポートされている不特定のフォーマット
  • 自分で解析する

今後のTemporal機能を使用する

このTemporal提案は、2021年8月のこの更新の時点でステージ3にあります。これを使用して、文字列をUTCまたは現地時間として処理して解析できます。

文字列をUTCとして扱う:

// (Getting the polyfill)
const {Temporal} = temporal;

const dateString = "2015-12-31 00:00:00";
const instant = Temporal.Instant.from(dateString.replace(" ", "T") + "Z");
// Either use the Temporal.Instant directly:
console.log(instant.toLocaleString());
// ...or get a Date object:
const dt = new Date(instant.epochMilliseconds);
console.log(dt.toString());
<script src="https://unpkg.com/@js-temporal/polyfill/dist/index.umd.js"></script>

または、現地時間として扱います。

// (Getting the polyfill)
const {Temporal} = temporal;

const dateString = "2015-12-31 00:00:00";

console.log("Parsing as local time:");
const tz = Temporal.Now.timeZone();
const instant = tz.getInstantFor(dateString.replace(" ", "T"));
console.log(instant.toLocaleString());
const dt = new Date(instant.epochMilliseconds);
console.log(dt.toString());
<script src="https://unpkg.com/@js-temporal/polyfill/dist/index.umd.js"></script>

Temporalタイムゾーンが指定されていないときに、指定された日付/時刻文字列形式が歴史的に持っていた以下の問題はありません。

指定された形式

スペースをに変更するTと、仕様になります。

var dateString = "2015-12-31 00:00:00";
// Treats the string as local time -- BUT READ BELOW, this varied
var d = new Date(dateString.replace(" ", "T"));
console.log(d.toString());

(実際には文字列リテラルを使用していないと想定しているため、replace呼び出しが行われます。)

Z古いブラウザで信頼性の高いタイムゾーン処理を行うには、 (GMT / UTCの場合)またはタイムゾーンインジケータ(+/ )を追加することもできます。- HH:MMこれは、文字列のない文字列の処理がES5で誤って指定され、ES2015で更新されてから、 ES2016でさらに更新されました。最新のブラウザの現在のバージョンは、現在の仕様に準拠しています。

  • 文字列に時間があり、タイムゾーンインジケーターがない場合は、現地時間で文字列を解析します
  • 文字列に時間がなく、タイムゾーンインジケーターがない場合は、UTCで文字列を解析します

ES5は常にデフォルトでUTCと言いました。ES2015は常にデフォルトで現地時間と言いました。ES2016は現在の動作が定義された場所です。それ以来安定しています。)

したがって、特に古いブラウザをサポートする必要がある場合は、タイムゾーンインジケータを含めることをお勧めします。Z(UTC)または+/でなければならないことに注意してください- HH:MM。のような略語CSTは、標準がないため許可されていません。UTCの例を次に示します。

var dateString = "2015-12-31 00:00:00";
// Treat the string as UTC
var d = new Date(dateString.replace(" ", "T") + "Z");
console.log(d.toString());

ほぼ普遍的にサポートされている不特定のフォーマット

仕様には含まれていないが、ほぼ普遍的にサポートされており、長い間使用されてきた2番目の形式がありますYYYY/MM/DD HH:MM:SS。これは現地時間として解釈されます。それで:

var dateString = "2015-12-31 00:00:00";
// Treats the string as local time
var d = new Date(dateString.replace(/-/g, "/"));
console.log(d.toString());

繰り返しになりますが、これは不特定の動作であるため、エンプターに注意してください。ただし、少なくともIE8 +(おそらく以前)、Chrome、およびV8 JavaScriptエンジン、Firefox、Safariを使用するその他のもので動作します。

自分で解析する

その文字列を自分で解析するのも簡単です。ES2020 +機能の使用:

function parseDate(str) {
    const [dateparts, timeparts] = str.split(" ");
    const [year, month, day] = dateparts.split("-");
    const [hours = 0, minutes = 0, seconds = 0] = timeparts?.split(":") ?? [];
    // Treats the string as UTC, but you can remove the `Date.UTC` part and use
    // `new Date` directly to treat the string as local time
    return new Date(Date.UTC(+year, +month - 1, +day, +hours, +minutes, +seconds));
}

const dateString = "2015-12-31 00:00:00";
const d = parseDate(dateString);
console.log(d.toString());

または、ES5レベルの機能のみを使用する場合(質問は2015年のものであるため):

function parseDate(str) {
    var parts = str.split(" ");
    var dateparts = parts[0].split("-");
    var timeparts = (parts[1] || "").split(":");
    var year = +dateparts[0];
    var month = +dateparts[1];
    var day = +dateparts[2];
    var hours = timeparts[0] ? +timeparts[0] : 0;
    var minutes = timeparts[1] ? +timeparts[1] : 0;
    var seconds = timeparts[2] ? +timeparts[2] : 0;
    // Treats the string as UTC, but you can remove the `Date.UTC` part and use
    // `new Date` directly to treat the string as local time
    return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds));
}

var dateString = "2015-12-31 00:00:00";
var d = parseDate(dateString);
console.log(d.toString());

于 2012-11-13T15:41:25.537 に答える
6

理由はわかりません。iOSがAndroidと同様にJavascriptDate関数をサポートしていないためか、別の形式をサポートしているためでしょうか。

しかし、私はあなたに回避策を与えることができます:

var s = "2015-12-31 00:00:00".split(" ")[0].split("-"),
    d = new Date( s[0], s[1], s[2], 0, 0, 0 );

console.log(d);

var s = "2015-12-31 00:00:00".replace(/[ :]/g, "-").split("-"),
    d = new Date( s[0], s[1], s[2], s[3], s[4], s[5] );

console.log(d);
于 2012-11-13T15:38:21.050 に答える
5

IOSとAndroidの両方で機能し、不要な場合は文字列操作を回避するソリューションは次のとおりです。

let fullDate = "1991-03-29 00:00:00";
let date = new Date(fullDate);

// In case its IOS, parse the fulldate parts and re-create the date object.
if(Number.isNaN(date.getMonth())) {
  let arr = fullDate.split(/[- :]/);
  date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
}
于 2018-10-23T17:03:17.603 に答える
0

誰かがまだそれを探しているなら。

IE、Safari、IOS-FF、IOS-Safariなどで動作します。

getIOSSaveDateObj = function(dateString){
    if(dateString.indexOf('-') > 0){
        var arr = dateString.split(/[- :]/);
        var date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
    }else{
        var arr = dateString.split(/[. :]/);
        var date = new Date(arr[2], arr[1]-1, arr[0], arr[3], arr[4], arr[5]);
    }
    return date;
}
于 2020-03-20T01:20:02.833 に答える
0

私はこれを解決しようとするのにとても苦労しました、私は最終的にもっと簡単な解決策を探して、 moment.jsを使いました。日付を宣言するだけで、すべてのデバイスで機能する必要はありません。

于 2020-04-16T18:09:03.680 に答える
-1

Worksformeを試してみてvar d = new Date("2015/12/31 00:00:00");ください。

于 2012-11-13T15:38:28.323 に答える
-3

また

var d = new Date("2015/12/31T00:00:00");

私のために働く:)

ありがとう@dda

于 2016-09-13T12:48:48.937 に答える