2

UniVerse 版本 11.2.4 的发行说明提到了本地时区配置,但它是在审计的上下文中。这是报价:

本地时区配置

在 UniVerse 11.2.4 之前,审计日志记录中存储的日期和时间数据仅基于 UTC。从 UniVerse 11.2.4 开始,UniVerse 将基于本地时区的日期和时间数据添加到审核日志记录中。对于每条记录,数据都存储在位置 19 中。此数据字段的字典名称是 TZINFO。有关详细信息,请参阅 UniVerse 安全功能。

由于 UniVerse 似乎能够在本地处理时区,这是否意味着可能有一种方法可以从我的 EST/EDT 值轻松生成 UTC 格式的日期/时间戳?

我正在将数据发送到一个需要以 ISO-8601 日期/时间格式格式化日期的系统yyyy-MMddTHH:mm:ssZ,例如2015-06-02T15:55:22Z,考虑时区和夏令时偏移量。

我翻阅了安全功能指南,发现了这一点:

UniVerse 还增加了一个全局编目程序,帮助用户从审计日志中获取日期和时间信息(由上述两个 I-descriptor 字段调用):

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 次,而且我们已经强制执行了!这对我们这些肉机来说都很好,他们只想在对我们方便的时候了解时间,但是当我们报告“看起来很有趣”时,它确实会导致我们脾气暴躁。

您的问题的解决方案并非特别简单,尤其是在您使用已记录的日期时。Universe 中的日期和时间通常根据本地系统时间记录。如果这是您今后尝试做的事情,您必须记下交易时的偏移量,或者简单地标记 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 回答