有効期限が&であるレコードがデータストアにあります。この情報は、Instant
という文字列表現を使用して格納されます。インスタントのtoStringの前にプラス
期限切れにならないレコードがあります。しかし、有効期限の値は必須であるため、Instant.MAX
の文字列表現を格納することに決めました。
これまでのところとても良いです。入力時間範囲[s,e]
内でアクティブなすべてのレコードを返す検索ユースケースがあります。データストアを照会し、そのようなすべてのレコードを返しますSi < s && e < Ei
を満たす[Si, Ei]
ここでは文字列表現を比較しています。
ここで問題は、がInstant.MAX
の文字列表現の先頭に追加されていることです。これはASCII('+') < ASCII(digit)
からe < Ei
という条件に失敗しています。
私は、+
開始を前に追加取得second
た後に知るためにコードの一部を書いた:
Long e = Instant.now().getEpochSecond()*1000;
for (int i = 0; i < 5; i++) {
System.out.println(e + "->" + Instant.ofEpochMilli(e));
e *= 10;
}
印刷した:
1471925168000->2016-08-23T04:06:08Z
14719251680000->2436-06-07T17:01:20Z
147192516800000->6634-05-07T02:13:20Z
1471925168000000->+48613-06-14T22:13:20Z
14719251680000000->+468404-07-08T06:13:20Z
私は+
を切り捨てるのオプションをしましたデータストアで永続化する前に私はなぜこれが起こっているのか、明示的に避けることができるのか、もっと興味がありますか?
9999を超えるすべての年の先頭の正符号は有効なISO-8601形式です。IMHO無限の境界を実現するため、または文字列の比較に頼るために、有限の値(Instant.MAX)を使用するのはちょっと疑問です。インスタントオブジェクトの比較に基づいて、アプリケーションサーバーレイヤーでインスタントを取得したり照会したりすることはできませんか?または、db/storeに経過秒数(数値として)を格納することもできます。 –
それを指摘してくれてありがとう。比較はDB自体で行う必要があり、唯一許される比較は整数と文字列です。私はepoch秒の代わりに文字列表現を使用しているので、データを手動で照会すると読みやすくなります。 – nitish712
ISO委員会が9999年を超えて+をプレフィックスとして選択したことは悲しいことです.ISO形式の優れた特性は、標準ASCII /ユニコードストリングの順序と時刻の順序が一致し、+記号が違反していることです。どんな手紙も9999を超えてそれを保存していたでしょう。さらにいくつか調整すれば、0000より前の日付にこれを拡張することも可能です。 – chi