Convert UTC 'TimeGenerated' to local time in Azure monitor/log/analytics, when using "summarize by" - azure-log-analytics

I have this simple query
MyLog
| summarize avg(executionTimeInMS_d) by bin(TimeGenerated, 5min)
I'd like the summary to be in my local time zone, not UTC. This does not work :
MyLog
| summarize avg(executionTimeInMS_d) by bin(TimeGenerated-5, 5min)
Can this be done?

datetime values are in UTC.
if you know the timezone offset (at the time you run the query), you can subtract/add it to your datetime values as explained here: https://learn.microsoft.com/en-us/azure/kusto/query/datetime-timespan-arithmetic
for example: print now() - 7h

There is now a "Display time zone" setting in the App Insights query page. This will convert the timestamp to the selected timezone. It will also show the timezone in the timestamp column heading.
This only seems to work if you output the timestamp directly. If you apply any operations it reverts to UTC.

Best to convert using the datetime_utc_to_local() function. This way you can dynamically handle daylight savings within the query and don't need to depend on the UI.
AzureDiagnostics
| extend CentralTime = datetime_utc_to_local(TimeGenerated, "US/Central")

You can do this by subtracting/adding the time different from UTC. For example, to convert to EST. I subtracted 5h from TimeGenerated which is in UTC.
AppServiceConsoleLogs
| extend EasternTime = TimeGenerated - 5h
| sort by EasternTime desc
| project Level, EasternTime, ResultDescription

Related

How to select timestamptz with offset with AT TIME ZONE

I've fiddeling around with timestamps in PostgreSQL, reading a interesting Blog about this behavior, but have no clue to solve following problem:
How to select a 'timestamp with time zone' column with AT TIME ZONE from another column, including the offset to UTC in one step?
I've a sample table in PostgreSQL 10:
CREATE TABLE public.test_tz
(
id serial,
in_zone_timestamp timestamp without time zone,
in_zone character varying COLLATE pg_catalog."default",
CONSTRAINT test_tz_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
PostgreSQL's setting is
timezone=localtime
and the server runs at 'Europe/Berlin'
$ date --> Fri Mar 9 12:15:23 CET 2018
The timestamp column should store with this messy syntax:
INSERT INTO public.test_tz ( in_zone_timestamp, in_zone) VALUES
('2017-02-01 00:00:00' AT TIME ZONE current_setting('TIMEZONE') AT TIME ZONE 'Asia/Singapore', 'Asia/Singapore' );
If someone knows a better way, please don't hold back! The other solution is to use '2017-02-01 00:00:00-08' as the value, but I don't know the offset value.
I want to store the local timestamp like: 'The user hit a key at 2017-02-01 00:00:00 in Singapore'.
If I ask the database: Which time it was here in Europe, when the user in Singapore is hitting a key, I got:
SELECT in_zone_timestamp FROM public.test_tz;
--> '2017-01-31 17:00:00+01'
This seems OK, because Singapore has a offset of +8 hours.
If I want to know, which time it was in Singapore, I use:
SELECT in_zone_timestamp AT TIME ZONE in_zone FROM public.test_tz;
--> '2017-02-01 00:00:00'
That's OK too, but however, it doesn't return the offset to 'UTC', so I can't see that this timestamp is not in my local time!
I try some combinations of AT TIME ZONE or converting to timestamptz, but the results are not what I want. I expected a result like:
--> '2017-02-01 00:00:00+08'
At here, I only see one solution, to manually concat/convert/manipulate the result and add the offset by hand, but is this the only way?
Sorry if I explain this question a little bit too comlicated and hope someone can follow my thoughts.
Thanks in advance
The only way to have PostgreSQL convert a timestamp to a string like 2017-02-01 00:00:00+08 automatically is to change the session time zone:
SET timezone = 'Asia/Singapore';
You can use SET LOCAL to change the setting only for the duration of a transaction.
If you don't want that, you can get the offset with a query like this:
SELECT TIMESTAMP '2000-01-01 00:00:00' AT TIME ZONE 'UTC'
- TIMESTAMP '2000-01-01 00:00:00' AT TIME ZONE 'Asia/Singapore';
?column?
----------
08:00:00
(1 row)
Thanks for clarify, but in my opinion that PostgreSQL has a few shortcomings on this topic.
A 'not so perfect' solution for this problem is really to manually concat the parts needed.
SELECT (test_tz.in_zone_timestamp AT TIME ZONE in_zone) || (SELECT abbrev FROM pg_timezone_names WHERE name = in_zone) FROM public.test_tz;
--> 2017-02-01 00:00:00+08
This provides an acceptable solution, with small imperfections.
In some cases there is the timezone short text in the abbrev-column, like 'CET' or 'PDT' and not the +/- numeric value. This produces results (eg. for 'Europe/Berlin') like:
--> 2017-02-01 02:00:00CET
A better value gives the column 'utc_offset' of pg-timezone-names, but this requires a more complex text manipulation, I don't want at this point.
Second solution can be the manipulation of the output by application and formatting the text to whatever you need.
Hope that helps others to solve such problem without searching the internet for a not available support from the database.
Bye

get time for timezone

I'm hurting my head again this :
On postgresql, I would like to get the local time for a given timezone.
So, at 15:45 GMT, I want 16:45 for +01:00, but I can't get the good anwser :
SQL Fiddle
Query 1:
select current_timestamp at time zone 'GMT' as time_local_gmt
Results:
| time_local_gmt |
|-----------------------------|
| 2018-01-26T15:45:10.871659Z |
This is OK.
Query 2:
select current_timestamp at time zone '+01:00' as time_local_paris
Results:
| time_local_paris |
|-----------------------------|
| 2018-01-26T14:45:10.871659Z |
This is totally wrong, seem like it's -01:00 instead of +01:00
Edit :
See the valid answer here : https://stackoverflow.com/a/48707297/5546267
This worked for me.
select current_timestamp at time zone 'UTC+1';
Gave me the following result.
2018-01-26T17:00:58.773039Z
There is also a list of timezone names.
Here is an excerpt from the PostgreSQL 9.6 documentation regarding timezone names.
The view pg_timezone_names provides a list of time zone names that are recognized by SET TIMEZONE, along with their associated abbreviations, UTC offsets, and daylight-savings status.
Basically, the following query will give you the current time in Paris.
SELECT current_timestamp AT TIME ZONE 'Europe/Paris';
Good Luck!
For completeness (even if #Avi Abrami's answer should be what you're searching for) let's take a look at the datetime operators in the docs.
One can use the INTERVAL keyword to add hours to the stored value:
SELECT current_timestamp AT TIME ZONE INTERVAL '+02:00' AS plus_two;
Which then results in
2018-01-26T17:45:10.871659Z
(when GMT time is 2018-01-26T15:45:10.871659Z)
Section 9.9.3 AT_TIME_ZONE mentions my use of INTERVAL without any preceeding operator:
In these expressions, the desired time zone zone can be specified either as a text string (e.g., 'PST') or as an interval (e.g., INTERVAL '-08:00'). In the text case, a time zone name can be specified in any of the ways described in Section 8.5.3.
The documentation says:
Another issue to keep in mind is that in POSIX time zone names, positive offsets are used for locations west of Greenwich. Everywhere else, PostgreSQL follows the ISO-8601 convention that positive timezone offsets are east of Greenwich.
I guess that is your problem.
Ok, finally found how to !
SELECT
current_timestamp
AT TIME ZONE 'GMT'
AT TIME ZONE '+01:00'
AS time_local_paris_right;
The timestamp is UTC without TZ by default, you force it as a GMT one, and then the second AT convert it with the right offset to give you the local time for the specified time zone.
SQL Fiddle
PostgreSQL 9.6 Schema Setup:
Query 2:
select current_timestamp at time zone 'GMT' as time_local_gmt
Results:
| time_local_gmt |
|-----------------------------|
| 2018-02-09T13:44:56.824107Z |
Query 3:
select current_timestamp at time zone '+01:00' as time_local_paris_wrong
Results:
| time_local_paris_wrong |
|-----------------------------|
| 2018-02-09T12:44:56.824107Z |
Query 4:
select current_timestamp at time zone 'GMT' at time zone '+01:00' as time_local_paris_right
Results:
| time_local_paris_right |
|-----------------------------|
| 2018-02-09T14:44:56.824107Z |

date_trunc in hive is working incorrectly

I am running below query:
select a.event_date,
date_format(date_trunc('month', a.event_date), '%m/%d/%Y') as date
from monthly_test_table a
order by 1;
Output:
2017-09-15 | 09/01/2017
2017-10-01 | 09/30/2017
2017-11-01 | 11/01/2017
Can anyone tell me why for date "2017-10-01" it is showing me date as "09/30/2017" after using date_trunc.
Thanks in Advance...!
You are reverse formatting so it is incorrect.
Use the below Code
select a.event_date,
date_format(date_trunc('month', a.event_date), '%Y/%m/%d') as date
from monthly_test_table a
order by 1;
You can use date_add with a logic to subtract 1-day(yourdate) to replicate trunc.
For eg:
2017-10-01 - day('2017-10-01') is 1 and you add 1-1=0 days
2017-08-30 - day('2017-08-30') is 30 and you add 1-30=-29 days
I faced the same issue recently and resorted to using this logic.
date_add(from_unixtime(unix_timestamp(event_date,'yyyy-MM-dd'),'yyyy-MM-dd'),
1-day(from_unixtime(unix_timestamp(event_date,'yyyy-MM-dd'),'yyyy-MM-dd'))
)
PS: As far as i know, there is no date_trunc function in Hive documentation.
As per the source code below: UTC_CHRONOLOGY time is translated w.r.t. locale, also in Description it is mentioned that session timezone will be the precision, also refer to below URL.
#Description("truncate to the specified precision in the session timezone")
#ScalarFunction("date_trunc")
#LiteralParameters("x")
#SqlType(StandardTypes.DATE)
public static long truncateDate(ConnectorSession session, #SqlType("varchar(x)") Slice unit, #SqlType(StandardTypes.DATE) long date)
{
long millis = getDateField(UTC_CHRONOLOGY, unit).roundFloor(DAYS.toMillis(date));
return MILLISECONDS.toDays(millis);
}
See https://prestodb.io/docs/current/release/release-0.66.html:::
Time Zones:
This release has full support for time zone rules, which are needed to perform date/time calculations correctly. Typically, the session time zone is used for temporal calculations. This is the time zone of the client computer that submits the query, if available. Otherwise, it is the time zone of the server running the Presto coordinator.
Queries that operate with time zones that follow daylight saving can
produce unexpected results. For example, if we run the following query
to add 24 hours using in the America/Los Angeles time zone:
SELECT date_add('hour', 24, TIMESTAMP '2014-03-08 09:00:00');
Output: 2014-03-09 10:00:00.000

Selecting where timestamp greater than with timezone

Suppose I have this table structure:
Table "test"
Column | Type | Modifiers
----------------+-----------------------------+-----------
uuid | uuid | not null
created | timestamp without time zone | not null
How would I select records after a certain date? But also factor in a specific timezone?
Since created is timestamp without zone, we can assume it's UTC
Example query:
select uuid from test where created >= '2017-07-20'
This would return all events that happend on, or after 2017-07-20 00:00:00.000 UTC How would I query for events that happend after say, 2017-07-20 00:00:00.000 GMT+2 ? Without having to add hours to my argument in created > arg
select uuid
from test
where created > '2017-07-20'::timestamp with time zone at time zone '+02';
I think one approach would be to compare the number of seconds since the epoch between your UTC timestamp in the table and some other input:
select uuid
from test
where
extract(epoch from created) >
extract(epoch from timestamp with time zone
'2017-07-19 23:59:59.999'::timestamp with time zone at time zone 'GMT')
The above syntax is verbose, and there may be a shorter way of writing this query. As a general rule, when you find yourself jumping through hoops to answer simple queries, it might mean you need to change your design. If you were storing your timestamps in UTC and running queries from an application, you would probably be passing in local timestamps already converted to UTC, which would make things much simpler.

How can I get a UTC timestamp in SQL400 on iSeries?

Our iSeries (aka AS400, aka i5, aka SystemI) runs in local time, but we have an application, that uses UTC (written in Java, connected by JDBC to the iSeries DB).
How can I generate UTC-timestamps via SQL on that system?
DB2/400 (which likes to be different in details from other DB2 flavours), has a special register called CURRENT TIMEZONE. It contains a numeric value, that can be subtracted from a timestamp or time value.
In an example query:
SELECT
CURRENT TIMESTAMP AS local,
CURRENT TIMEZONE AS offset,
CURRENT TIMESTAMP - CURRENT TIMEZONE AS utc
FROM SYSIBM.SYSDUMMY1
Gives you something like:
+----------------------------+--------+----------------------------+
| LOCAL | OFFSET | UTC |
+----------------------------+--------+----------------------------+
| 2014-05-27 14:09:19.127339 | 20.000 | 2014-05-27 12:09:19.127339 |
+----------------------------+--------+----------------------------+
Notes:
This example has an offset of +2 hours for central European summer time.
SYSIBM.SYSDUMMY1 is a special table supplied by IBM, with the sole purpose of having exactly one row with exactly one column.
Things like NOW() - CURRENT TIMEZONE and CURRENT TIME - CURRENT TIMEZONE work as well.
Reference in IBM's iSeries information center