Part of the problem is that I had mis-read the portion of the ConvertToLocalTime
docs, namely that it requires a GMT or UTC timestamp to operate. (I'm accustomed to other programming languages where the timezone is stored in or with the timestamp and can adjust automatically.)
Another aspect to this (not stated in the original question) is that QV is relying on the underlying OS for some timezone information, and I believe that Windows (ergo both QV desktop and QV server) is doing something odd, I think incorrect: despite the fact that UTC does not observe daylight savings time, Windows provides different times for "UTC" and "UTC+00:00". (If there is a valid explanation for this behavior, please comment!)
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
(Double quotes are shown above for the text, single-quotes for the actual function call.) ConvertToLocalTime()
has a third argument, ignore_dst
which may be used to mitigate this, but because it's a nuclear option that cannot be safely applied to non-UTC timezones, I cannot programmatically deal with time zones without several other checks.
Bottom line: QV does not store the time zone with a timestamp. That is, it relies on the programmer to track the source of the timestamp and do conversion as needed. This suggests that if time zones are ever used or in question, all data should be stored in "UTC" proper (not "UTC+00:00") so that ConvertToLocalTime()
can be used to easily convert into other zones. (Many suggested TZ best practices apply here.)
Related: not all database timestamp types are supported by QV. For example, SQL Server's datetimeoffset
is not supported, so manual parsing is required in order to preserve time zone and correctly use the numeric/timestamp dual.