4

次の構文を使用しています

TIMESTAMPDIFF(2, CHAR(CREATED - TIMESTAMP('1970-01-01 00:00:00'))

CREATEDタイプTIMESTAMPで、データベースは DB2 です。意図は、エポックからミリ秒に変換されたタイムスタンプを取得することです。もっと便利な機能があれば。

サンプルデータ:返される値は です
が、実際の値は である必要があります( http://www.epochconverter.comから取得)2011-10-04 13:54:5013166132901317732890

実行するクエリ

SELECT TIMESTAMPDIFF(2, CHAR(TIMESTAMP('2011-10-04 13:54:50') - TIMESTAMP('1970-01-01 00:00:00'))) FROM  SYSIBM.SYSDUMMY1;
4

3 に答える 3

8

これは、予想どおり、実際の値ではなく、タイムスタンプ間の差の推定値TIMESTAMPDIFFを返すという事実の結果です。

リファレンスの435 ページ (iSeries の場合) から:

要素の値を要求された間隔タイプに変換するときは、次の仮定が使用されます。

  • 1年は365日です。
  • 1年は52週です。
  • 1年は12ヶ月です。
  • 1 四半期は 3 か月です。
  • 1 か月は 30 日です。
  • 1 週間は 7 日です。
  • 1 日は 24 時間です。
  • 1時間は60分です。
  • 1分は60秒です。
  • 1 秒は 1000000 マイクロ秒です。

実際に使用される計算は次のとおりです。

秒 + (分 + (時間 + ((日 + (月 * 30) + (年 * 365)) * 24)) * 60) * 60

これは、明らかな理由から不正確です。役に立ちません。

これは、タイムスタンプの算術結果が返される方法の直接的な結果のようです。
あれは;

SELECT                                                              
TIMESTAMP('1971-03-02 00:00:00') - TIMESTAMP('1970-01-01 00:00:00') 
FROM sysibm/sysdummy1        

戻り値:

10,201,000,000.000000         

Which can be divided into:
  • 1
  • 02
  • 01日々
  • 00時間
  • 00
  • 00
  • 000000マイクロ秒

これは不正確な期間/期間情報です。このタイプのデータ役立つ状況は数多くありますが、これはその 1 つではありません。

簡単な答え:データベースでは正確な答えを正しく計算することはできません


長い答え:

計算は可能ですが、かなり複雑で、データベース内での計算には適していません。ここでそれらを再現するつもりはありません (興味があれば、特にさまざまなサブクラスについて JodaTimeChronologyを調べてください)。あなたの最大の問題は、月がすべて同じ長さではないという事実です。また、タイムスタンプが UTC 以外の場合、大きな問題が発生します。具体的には、サマータイムが計算に大混乱をもたらすことになります。なんで?オフセットは、どの国でもいつでも変更できるためです。

ミリ秒数が必要な理由を説明できますか? Java を使用している (または使用できる) ことを願っていますjava.time。しかし、iSeries を使用している場合は、おそらく RPG です...

于 2011-10-06T17:40:01.630 に答える
1

v9.7インフォセンターによると、TIMESTAMPDIFFは、1年の365日(時間の25%までは真ではない)、1か月の30日(75%の時間は真ではない)に基づいて、推定時間差を返します。それよりも少し良いです)、1日24時間(一部のタイムゾーンでは1年のうち2日は当てはまりません)、1時間に60分(やったー、1つです!)、1分に60秒(本当> 99.9時間の%-うるう秒を取得します)。

したがって、これはDB2でエポックタイムを取得する方法ではありません。これまでのところ、タイムスタンプとして時刻を取得し、それをクライアントで変換することに頼ってきました。

于 2011-10-06T17:15:28.227 に答える
1

Part of your error occurs because of the inaccuracy of the TIMESTAMPDIFF function, as others have pointed out.

The other source of error occurs because the Epoch is based on GMT – so you have to take your local timezone into account.

So, you can do this with the following expression:

(DAYS(timestamp('2011-10-04-13.54.50.000000') - current timezone) - DAYS('1970-01-01-00.00.00.000000')) * 86400 + MIDNIGHT_SECONDS(timestamp('2011-10-04-13.54.50.000000') - current timezone)

これを単純化するために、単純な UDF を作成できます。

create or replace function epoch (in db2ts timestamp)
   returns bigint
   language sql
   deterministic
   no external action
   return (days(db2ts - current timezone) - days('1970-01-01-00.00.00.000000')) * 86400 + midnight_seconds(db2ts - current timezone);

幸運を、

于 2011-10-07T08:09:58.920 に答える