2

UniVerse バージョン 11.2.4 のリリース ノートでは、ローカル タイム ゾーンの構成について言及されていますが、これは監査のコンテキストにあります。これは引用です:

ローカル タイム ゾーンの設定

UniVerse 11.2.4 より前では、監査ログ レコードに保存された日付と時刻のデータは UTC のみに基づいていました。UniVerse 11.2.4 以降、UniVerse はローカル タイムゾーンに基づく日付と時刻のデータを監査ログ レコードに追加します。データは、各レコードのロケーション 19 に保管されます。このデータ フィールドの辞書名は TZINFO です。詳細については、UniVerse セキュリティ機能を参照してください。

UniVerse はタイム ゾーンをネイティブに処理できるようですが、これは、EST/EDT 値から UTC 形式の日付/タイム スタンプを簡単に生成する方法があることを意味しますか?

タイムゾーンと夏時間のオフセットを考慮して、 のyyyy-MMddTHH:mm:ssZようなISO-8601 日付/時刻形式でフォーマットされた日付が必要なシステムにデータを送信しています。2015-06-02T15:55:22Z

セキュリティ機能ガイドを掘り下げたところ、次のことがわかりました。

UniVerse は、グローバルにカタログ化されたプログラムを追加して、ユーザーが監査ログから日付と時刻の情報を取得できるようにします (これは、上記の 2 つの I 記述子フィールドによって呼び出されます)。

SUBROUTINE GETLOCALTIME
(
RESULT ;* OUT: output
TZOFF ;* IN: time zone offset
DATE ;* IN: UTC date
TIME ;* IN: UTC time
OP ;* IN: operation
;* 1: get local date
;* 2: get local time
;* 3: get local timezone id
;* 4: get local timezone daylight saving flag
)

(私は UniVerse の監査機能を使用していないので、これでできることはあまりないと思いますし、サブルーチンを見つけることもできませんでした。)

DATE.UTILITY PickWikiの人気のある (?)プログラムも試してみましたが、夏時間の開始日と終了日の計算がずれているようです。これらの問題は別の質問のために取っておきます。

これは長くなりつつありますが、新しい OCONV() パラメーターまたは使用できるものがあれば、誰かが私を正しい方向に向けることができることを願っています。

念のため、私は Windows Server 2008 R2 で実行しています。

ありがとう!

4

2 に答える 2

0

時間は複雑なものです。社会的には、年に 2 回の変更が許容されるだけでなく、義務付けられていることも認められています。これは、私たちにとって都合の良い時間だけを理解したいと思っているミートマシンにとってはまったく問題ありませんが、「変に見える」と報告すると不機嫌になります.

問題の解決策は、特に既に記録された日付で作業している場合、非常に簡単ではありません。ユニバースの日付と時刻は、通常、ローカル システム時刻に基づいて記録されます。これが今後行おうとしているものである場合は、トランザクションの時点でオフセットが何であるかを記録するか、単純に SYSTEM(99) をスタンプする必要があります。これにより、実行する必要がある他のすべてのレポートがかなり複雑になります。いずれにせよ、これは複雑な問題であり、まだ不完全である可能性があります。

これは、あなたが今後のレコーディングの担当者である場合に役立つかもしれないちょっとしたものです.

SECONDS.SINCE.GMT.01.01.1970 = SYSTEM(99) 
CRT SECONDS.SINCE.GMT.01.01.1970:" Seconds since GMT Epoch Began"

NUMBER.OF.DAYS.SINCE.01.01.1970 = DATE() -732 
;* Day 0 in Pick is 12/31/1967 because Dick Pick so we subtract 732 from the pick date

SECONDS.SINCE.MIDNIGHT.LOCAL= TIME()
SECS.PER.DAY = 24 * 60 * 60
LOCAL.SECONDS.SINCE.GMT.01.01.1970 = NUMBER.OF.DAYS.SINCE.01.01.1970 * SECS.PER.DAY + FIELD(SECONDS.SINCE.MIDNIGHT.LOCAL,".",1) 
;*I drop the precision
CRT LOCAL.SECONDS.SINCE.GMT.01.01.1970: " Seconds since 01/01/1970 in local time"

OFFSET = (LOCAL.SECONDS.SINCE.GMT.01.01.1970 - SECONDS.SINCE.GMT.01.01.1970)
CRT "CURRENT.OFFSET IS ":INT((OFFSET / 60 )/ 60)
END

現在PDTであるシステムで次を出力します(OCONV(DATE()、 'DZ')はPSTとして報告しますが)。

1434472817 Seconds since GMT Epoch Began
1434447617 Seconds since 01/01/1970 in local time
CURRENT.OFFSET IS -7

うまくいけば、これは役に立ちました。

于 2015-06-16T16:44:59.587 に答える
0

手がかりをありがとう。これが私の実装です:

  SUBROUTINE FORMAT.ISO.8601 (IDATE, ITIME, RESULT, ERR.TEXT)

  * Don't step on the caller's variables.
  IN.DATE = IDATE
  IN.TIME = ITIME

  * Initialize the outbound variable.
  RESULT = ''

  IF NOT(NUM(IN.DATE)) THEN
     ERR.TEXT = 'Non-numeric internal date ' : DQUOTE(IN.DATE) : ' when numeric required.'
     RETURN
  END

  IF NOT(NUM(IN.DATE)) THEN
     ERR.TEXT = 'Non-numeric internal time ' : DQUOTE(IN.TIME) : ' when numeric required.'
     RETURN
  END

  * SYSTEM(99) is based on 1/1/1970.
  SECONDS.SINCE.GMT.01.01.1970 = SYSTEM(99)

  * Day 0 in Pick is 12/31/1967
  * Subtract 732 to equalize the starting dates.
  NUMBER.OF.DAYS.SINCE.01.01.1970 = DATE() - 732

  SECONDS.SINCE.MIDNIGHT.LOCAL= TIME()
  SECS.PER.DAY = 24 * 60 * 60
  LOCAL.SECONDS.SINCE.GMT.01.01.1970 = NUMBER.OF.DAYS.SINCE.01.01.1970 * SECS.PER.DAY + FIELD(SECONDS.SINCE.MIDNIGHT.LOCAL,".",1)

  OFFSET = LOCAL.SECONDS.SINCE.GMT.01.01.1970 - SECONDS.SINCE.GMT.01.01.1970

  OFFSET = INT((OFFSET / 60 )/ 60)

  OTIME = OCONV(IN.TIME, 'MTS')
  IF OTIME = '' THEN
     ERR.TEXT = 'Bad internal time ' : DQUOTE(IN.TIME) : '.'
     RETURN
  END

  HOURS = FIELD(OTIME, ':', 1)
  MINUTES = FIELD(OTIME, ':', 2)
  SECONDS = FIELD(OTIME, ':', 3)

  HOURS -= OFFSET
  IF HOURS >= 24 THEN
     IN.DATE += 1
     HOURS = HOURS - 24
  END
  HOURS = HOURS 'R%2'

  ODATE = OCONV(IN.DATE, 'D4/')
  IF ODATE = '' THEN
     ERR.TEXT = 'Bad internal date ' : DQUOTE(IN.DATE) : '.'
     RETURN
  END

  DMONTH = FIELD(ODATE, '/', 1)
  DDAY = FIELD(ODATE, '/',2)
  DYEAR = FIELD(ODATE, '/',3)

  RESULT = DYEAR : '-' : DMONTH : '-' : DDAY : 'T' : HOURS : ':' : MINUTES : ':' : SECONDS : 'Z'

  RETURN

END

これが私のテストハーネスです:

  CRT 'Testing right now.'
  IDATE = DATE()
  ITIME = TIME()
  CALL FORMAT.ISO.8601 (IDATE, ITIME, RESULT, ERR.TEXT)
  IF ERR.TEXT THEN
     CRT 'ERR.TEXT: ' : ERR.TEXT
  END ELSE
     CRT 'RESULT: ' : RESULT
  END

  CRT
  CRT 'Testing an hour ago.'
  IDATE = DATE()
  ITIME = TIME()
  ITIME = ITIME - (60*60)
  IF ITIME < 0 THEN
     ITIME += (24*60*60)
     IDATE -= 1
  END
  CALL FORMAT.ISO.8601 (IDATE, ITIME, RESULT, ERR.TEXT)
  IF ERR.TEXT THEN
     CRT 'ERR.TEXT: ' : ERR.TEXT
  END ELSE
     CRT 'RESULT: ' : RESULT
  END

  CRT
  CRT 'Testing an hour from now.'
  IDATE = DATE()
  ITIME = TIME()
  ITIME = ITIME + (60*60)
  IF ITIME > (24*60*60) THEN
     ITIME -= (24*60*60)
     IDATE += 1
  END
  CALL FORMAT.ISO.8601 (IDATE, ITIME, RESULT, ERR.TEXT)
  IF ERR.TEXT THEN
     CRT 'ERR.TEXT: ' : ERR.TEXT
  END ELSE
     CRT 'RESULT: ' : RESULT
  END

END

これが私のテスト実行です:

  >T$FORMAT.ISO.8601
  Testing right now.
  RESULT: 2017-03-29T00:47:22Z

  Testing an hour ago.
  RESULT: 2017-03-28T23:47:22Z

  Testing an hour from now.
  RESULT: 2017-03-29T01:47:22Z
于 2017-03-29T00:49:16.180 に答える