【问题标题】:QlikView and timezonesQlikView 和时区
【发布时间】:2017-04-08 14:57:13
【问题描述】:

为什么同一时间显示两次:

=Now() & ' ' & TimeZone() & '\n' & ConvertToLocalTime(Now(), 'UTC') & ' UTC'

这表明:

2017-04-08 07:53:27 GMT-08:00
2017-04-08 07:53:27 UTC

我正在尝试根据其开始时间戳是否为“将来”来有条件地格式化数据透视表表达式。有问题的字段是正确的(ConvertToLocalTime([Start Time], 'UTC') 显示正确的时间戳),本地时间也是正确的,但我无法准确地将我的本地非 UTC 时间与来自不同时区的另一个时间进行比较。

【问题讨论】:

    标签: datetime qlikview datetimeoffset


    【解决方案1】:

    从帮助文件中您会注意到,这是将 UTC 或 GMT 时间戳转换为本地时间作为对偶值

    所以用法如下:

    =ConvertToLocalTime(UTC(), 'GMT-05:00')
    

    你的例子:

    =ConvertToLocalTime(UTC(), TimeZone() ) & ' ' & TimeZone() & '\n' & UTC() & ' UTC'
    

    帮助文件来源:http://help.qlik.com/en-US/qlikview/12.1/Subsystems/Client/Content/Scripting/DateAndTimeFunctions/converttolocaltime.htm

    【讨论】:

    • 这是解决一些问题的重要一步,最重要的是 ConvertToLocalTime 需要(并且被记录为这样)UTC/GMT 时间戳来做任何事情。这对于推断 Qlik 不包括时间戳中的“时区”非常有帮助。谢谢!
    【解决方案2】:

    部分问题是我误读了ConvertToLocalTime docs 的部分内容,即它需要 GMT 或 UTC 时间戳才能运行。 (我习惯了其他编程语言,其中时区存储在时间戳中或与时间戳一起,并且可以自动调整。)

    另一个方面(原始问题中未说明)是 QV 依赖于底层操作系统来获取一些时区信息,我认为 Windows(同时 QV 桌面和 QV 服务器)正在做一些奇怪的事情不正确:尽管UTC does not observe daylight savings time,Windows 为“UTC”和“UTC+00:00”提供了不同的时间。 (如果有对此行为的有效解释,请发表评论!)

    ConvertToLocalTime(UTC())                      : 2017-04-20 10:12:17
    ConvertToLocalTime(UTC(), "UTC")               : 2017-04-20 17:12:17
    ConvertToLocalTime(UTC(), "UTC+00:00")         : 2017-04-20 18:12:17 (huh?)
    ConvertToLocalTime(UTC(), "UTC+00:00", "True") : 2017-04-20 17:12:17
    

    (上面的文本用双引号表示,实际函数调用用单引号表示。)ConvertToLocalTime() 有第三个参数,ignore_dst 可以用来缓解这种情况,但因为它是一个核选项,不能安全地应用于非 UTC 时区,如果没有其他几项检查,我无法以编程方式处理时区。

    底线:QV 不存储带有时间戳的时区。也就是说,它依赖于程序员来跟踪时间戳的来源并根据需要进行转换。这表明,如果曾经使用过或有问题的时区,所有数据都应存储在“UTC”正确(而不是“UTC+00:00”)中,以便ConvertToLocalTime() 可用于轻松转换为其他时区。 (许多建议TZ best practices 在这里申请。)

    相关:并非所有数据库时间戳类型都受 QV 支持。例如,不支持 SQL Server 的datetimeoffset,因此需要手动解析以保留时区并正确使用数字/时间戳对偶。

    【讨论】:

    • 也许也可以试一试,QV 中的 ConvertToLocalTime 和 LocalTime 函数似乎有问题。因此,尝试创建自己的,快速执行如下操作:使用以下表达式创建一个变量Timestamp(UTC()+$1/24),然后按如下方式调用该变量$(vToTimezone(+2))$(vToTimezone(-2)) 在我的示例中,该变量被称为 vToTimezone 并且值 I我正在通过 +2 / -2 用于 GMT+02:00。您可以在 var 中进行额外的编码以满足您实际接受来自 datetimeoffset 的输入的需要
    • 一个问题是我正在处理约 1M SQL 行,其中一个字段中的时间戳将具有不同的时区。因为我不能提前知道它们,所以我解析字符串,提取时区,然后做一些类似的事情。我根据 SQL Server 的 datetimeoffset 数据类型使用了 SET DateTimeOffset2Serial=Timestamp#(left($1, 27)) + Num#(left(right($1, 5), 2))/24。感谢您的评论!
    • 请注意,QV 确实接受时间戳内的时区,请参阅此处 =Timestamp(Replace(Replace(Replace('2017-04-20 20:50:43.456 +02:00',' +','+'),' -','-'),' ','T')) 即为 QV 时间戳创建 datetimeoffset
    • 不错的建议。我对它们进行了基准测试,在计算时间上找不到显着差异。看起来您的方法可能更强大一点,因为它不依赖于字符串长度;除此之外,与left/right 函数相比,triple-Replace 是否有任何(可能是以 QV 为中心的)优势?
    • 我使用 replace x3 的唯一真正原因是首先替换毫秒和时区之间的空间,然后是日期和时间之间的空间。您也可以使用左右,但认为这将是更长的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多