0

このスレッドに関して、私は部分的な解決策を開発しました:

function strtosecs($time,$now=null){
    static $LEAPDIFF=86400;
    $time=strtotime($time,$now);
    return $time-(round((date('Y',$time)-1968)/4)*$LEAPDIFF);
}

この関数は、うるう年をチェックせずに、指定された文字列の秒数を取得することになっています。

1970 年のうるう年の数 [(year-1986)/4] を計算し、うるう年と通常の年の秒数の差を掛けます (最終的には、1970 年の秒数です)。一日)。

最後に、計算された時間から余分な閏年秒をすべて削除します。入力/出力の例を次に示します。

// test code
echo strtosecs('+20 years',0).'=>'.(strtosecs('+20 years',0)/31536000);
echo strtosecs('+1 years',0).'=>'.(strtosecs('+1 years',0)/31536000);

// test output
630676800 => 19.998630136986
31471200  => 0.99794520547945

おそらく、出力で除算を行う理由を尋ねるでしょう。それをテストすることです。31536000 は 1 年の秒数なので、19.99... は 20、0.99... は 1 になるはずです。確かに、すべてを四捨五入して「正しい」答えを得ることができましたが、不正確さ。

Edit1:明らかではないので、私の問題は不確実性にあります。20 年間 PHP に頼まなかっただけで、19.99 が得られます... ですよね?

Edit2:すべては 1968 年頃の部分に集約されるようです。

  • 1970; 私が試したすべてのテストで正確であることがわかりました。
  • 1969年; ここ( ...ex: (2008-1969)/4 = 9.75...)で使用されていることと、ここで言及されていることがわかりました。2年目(+3年)以降は正確。
  • 1968; 以下で詳しく説明するように、これは UNIX 時間 (1970 年) からのうるう年の「ゼロ年」です。(私には)「正しい」ように聞こえますが、まったく正確ではありませ
4

2 に答える 2

1

1968計算で (どこから来たのか?) を unix time の起源に置き換える必要が1970あります。そうすれば、より正確な結果が得られます。

編集

intval整数でなければならないうるう年の数を数えるには、次のようにする必要があります。

return $time - (intval( (date('Y', $time) - 1969) / 4) * $LEAPDIFF);

これにより、範囲内で正しい結果が得られ、+0 -> +6832ビットマシンでのUNIX時間の終了

于 2010-12-24T10:12:05.690 に答える
1

これは、PHP を使用して浮動小数点数を管理するときに発生する固有の不正確さに関連している可能性がありますか?

http://php.net/manual/en/language.types.float.php

于 2010-12-24T09:28:18.677 に答える