Why does this show the same time twice:
=Now() & ' ' & TimeZone() & '\n' & ConvertToLocalTime(Now(), 'UTC') & ' UTC'
This shows:
2017-04-08 07:53:27 GMT-08:00
2017-04-08 07:53:27 UTC
I'm trying to conditionally-format a pivot table expression based on whether its start timestamp is "in the future". The field in question is correct (ConvertToLocalTime([Start Time], 'UTC') shows the correct timestamp), and the local time is also correct, but I cannot accurately compare my local non-UTC time with another from a different time zone.
From the helpfile you will notice this is to convert a UTC or GMT timestamp to local time as a dual value
So usage would be as follows:
=ConvertToLocalTime(UTC(), 'GMT-05:00')
For your example:
=ConvertToLocalTime(UTC(), TimeZone() ) & ' ' & TimeZone() & '\n' & UTC() & ' UTC'
Helpfile source: http://help.qlik.com/en-US/qlikview/12.1/Subsystems/Client/Content/Scripting/DateAndTimeFunctions/converttolocaltime.htm
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.
Related
This question already has answers here:
How to make a timezone aware datetime object
(15 answers)
Closed 6 years ago.
I've got a datetime which has no timezone information. I'm now getting the timezone info and would like to add the timezone into the existed datetime instance, how can I do?
d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')
How to add the timezone info tz into datetime a
Use tz.localize(d) to localize the instance. From the documentation:
The first is to use the localize() method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information):
>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500
If you don't use tz.localize(), but use datetime.replace(), chances are that a historical offset is used instead; tz.localize() will pick the right offset in effect for the given date. The US Eastern timezone DST start and end dates have changed over time, for example.
When you try to localize a datetime value that is ambiguous because it straddles the transition period from summer to winter time or vice-versa, the timezone will be consulted to see if the resulting datetime object should have .dst() return True or False. You can override the default for the timezone with the is_dst keyword argument for .localize():
dt = tz.localize(naive, is_dst=True)
or even switch off the choice altogether by setting is_dst=None. In that case, or in the rare cases there is no default set for a timezone, an ambiguous datetime value would lead to a AmbiguousTimeError exception being raised. The is_dst flag is only consulted for datetime values that are ambiguous and is ignored otherwise.
To go back the other way, turn a timezone-aware object back to a naive object, use .replace(tzinfo=None):
naivedt = awaredt.replace(tzinfo=None)
If you know that your original datetime was "measured" in the time zone you are trying to add to it, you could (but probably shouldn't) use replace rather than localize.
# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)
I can imagine 2 times when this might make sense (the second one happened to me):
Your server locale is set to the incorrect time zone and you are trying to correct a datetime instance by making it aware of this incorrect timezone (and presumably later localizing it to the "correct" time zone so the values of now() match up to other times you are comparing it to (your watch, perhaps)
You want to "tag" a time instance (NOT a datetime) with a time zone (tzinfo) attribute so that attribute can be used later to form a full datetime instance.
I've found a couple of existing StackoverFlow questions on this but nothing very definite.
I have a local datetime. I want this in UTC. my local datetime does not have a 'Z' at the end or any offset information.
I first tried:
moment(mylocaldatetime).toISOString() #works fine because this method always returns time in UTC
But for consistency with other code I didn't want to use to ISOString() so I did this:
moment(mylocaldatetime).utc().format()
This seems to work fine. If the browser running this code is in UTC + 1 I get a datetime one hour less than mylocaldatetime (with an offset string if I specify that in the format). I.e. it has treated mylocaldatetime as a local time, taken account of my current time zone, and given me my local time as UTC.
However. This appears to contradict the moment.js docs which are pretty clear that:
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment(). - Notice the 'parse'.
and
Moment normally interprets input times as local times (or UTC times if moment.utc() is used).
If these doc comments were true this line:
moment(mylocaldatetime).utc().format()
should treat mylocaldatetime as if it were utc and then output this datetime in utc - no difference. No conversion. But that is not what I get.
Maybe what this line moment(mylocaldatetime).utc().format() is saying is:
create a moment object in local mode with mylocaldatetime. Then put the moment object into utc mode. So now when we format for display we output as utc. IF this is the case I think the docs could be made clearer.
I'm working on extracting a date from a variable: "curIndex."
Here's what the code looks likes
show(txntime1 <- timestamp(mktdata[curIndex+1L])[,1])
show(txntime <- strftime(txntime1, '%Y-%m-%d %H:%M:%OS6'))
And the output is this:
"##------ Tue Mar 08 14:31:58 2016 ------##"
"NULL"
I'm working within ruleOrderProc of the quantstrat package.
The order time needs to be POSIXlt for the order book. Does anyone know what to do with this funky date format that I'm getting?
If so, thanks!
When all else fails, read the documentation. ;-) ?timestamp says:
The timestamp function writes a timestamp (or other message)
into the history and echos it to the console. On platforms that
do not support a history mechanism only the console message is
printed.
You probably meant to call time or index. Also, the time needs to be POSIXct for the order book, not POSIXlt.
Does the below 2 syntaxes are same,
moment(1456261200367, 'H:mm:ss.SSS').utc().valueOf() //1456343786120
moment(1456261200367 +0000, 'H:mm:ss.SSS Z').valueOf() //1456325786120
but as you could see if both of them coverts the given value to UTC mode then why there is a difference in the output?
Also I would like to know how a.valueOf() and b.valueOf() are same, when a.format() and b.format() are different, because moment() (moment parses and displays in local time) is different from moment.utc() (displays a moment in UTC mode)
var a = moment();
var b = moment.utc();
a.format();
b.format();
a.valueOf();
b.valueOf();
In the first part, you're using it incorrectly. You've passed numeric input which would normally be interpreted as a unix timestamp, but then you've supplied a string-based format string so the number is converted to a string. The format string here is telling moment how the input is specified, but it doesn't match what you're actually parsing.
This doesn't error though, because by default moment's parser is in "forgiving" mode. You can read more about this in the docs.
The correct way to pass a timestamp into moment is with one of these:
moment(1456261200367)
moment(1456261200367).utc()
moment.utc(1456261200367)
The last two are equivalent, but the moment.utc(timestamp) form is prefered.
With any of those, all three will have the same .valueOf(), which is just the timestamp you started with. The difference is in the mode that the moment object is in. The first one is in local mode, reflecting the time zone of the computer where it's running, while the other two are in UTC mode.
This is evident when you format the output using the format function, as with other many other functions. I believe that answers your second question as well.
On a 32 bit OS, with an Intel processor,
DateTime e.g. 2/17/2009 12:00:00 AM
Notice that it is: mm/DD//yyyy
On a 64 bit OS, with an AMD processor,
DateTime e.g. 17-02-2009 00:00:00
Now when I try to parse the 1st format, it throws an error on the 2nd platform.
That means - DateTime.Parse("2/17/2009 12:00:00 AM") - throws an error - cannot convert.
whereas, on the same platform,
DateTime.Parse("17/2/2009 12:00:00 AM") works! That means DD/MM is fine, MM/DD is not.
What is causing this? The 64-bit OS? The processor?
How do I get rid of the problem?
DateTimes themselves don't have formats. You parse them or format them into strings. (It's like numbers - integers aren't stored in hex or decimal, they're just integers. You can format them in hex or decimal, but the value itself is just a number.)
The format will depend on the culture of the operating system (or more accurately, the culture of the thread, which is typically the same as the operating system one).
Personally I like to explicitly set the format I use for either parsing or formatting, unless I'm actually displaying the string to the user and know that the culture is appropriate already.
Check your "Date and time formats" in the "Region and Language" control panel.
Also, if you want DateTime to generate a specific format, don't just call plain ToString(), but pass it a parameter indicating the format you want. Similarly, if you know the format of the date you are asking it to parse, call TryParseExact(), and tell it the format you are providing.
See also MSDN's Standard Date and Time Format Strings