How do I convert gps time to date in BigQuery - sql

Currently I am using
SELECT TIMESTAMP_SECONDS(CAST(my_time_unix_ns/1000 AS int64)) AS my_date,...
But some of the columns store time in gps ns. How do I convert them into date?

There is no support for nanosecond precision within Cloud BigQuery. BigQuery CURRENT_TIMESTAMP() returns only up to milliseconds (Example:1), and the CAST() function supports only up to millisecond precision level (#Example-2, 3 and 4). For more context on timestamp precision, please refer to the supported range of BigQuery timestamps [1], which is 0001-01-01 00:00:00.000000 to 9999-12-31 23:59:59.999999.
On the other hand, I assume the Unix time function you are using returns an integer value larger than the capacity of Int64. Please refer to the numeric data type documentation [2]
Example-1:
SELECT CURRENT_TIMESTAMP() AS Current_Time
Result: 2019-12-24 17:51:44.419542 UTC
Example-2:
SELECT CAST('2019-12-24 00:00:00.000000' AS TIMESTAMP)
Result: 2019-12-24 00:00:00 UTC
Example-3:
SELECT CAST('2019-12-24 11:12:47.145482+00' AS TIMESTAMP)
Result: 2019-12-24 11:12:47.145482 UTC
Example-4:
SELECT CAST('2019-12-24 11:12:47.14548200' AS TIMESTAMP)
Result: error: "Could not cast literal "2019-12-24 11:12:47.14548200" to type TIMESTAMP "
[1] https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#timestamp-type
[2] https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#integer-type

Related

When to use DATE_TRUNC() vs. DATE_PART()?

I do not know when to use DATE_TRUNC and DATE_PART() in a query.
I have not really tried much, just some web searches that I do not fully grasp but I just started learning SQL (Postgres).
They both do very different things. One truncates a date to the precision specified (kind of like rounding, in a way) and the other just returns a particular part of a datetime.
From the documentation:
date_part():
The date_part function is modeled on the traditional Ingres equivalent
to the SQL-standard function extract:
date_part('field', source)
Note that here the field parameter needs to be a string value, not a
name. The valid field names for date_part are the same as for extract.
For historical reasons, the date_part function returns values of type
double precision. This can result in a loss of precision in certain
uses. Using extract is recommended instead.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4
date_trunct():
The function date_trunc is conceptually similar to the trunc function
for numbers.
date_trunc(field, source [, time_zone ]) source is a value expression
of type timestamp, timestamp with time zone, or interval. (Values of
type date and time are cast automatically to timestamp or interval,
respectively.) field selects to which precision to truncate the input
value. The return value is likewise of type timestamp, timestamp with
time zone, or interval, and it has all fields that are less
significant than the selected one set to zero (or one, for day and
month).
...
Examples (assuming the local time zone is America/New_York):
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00

SQL: Combine columns to specific datetime and cast to UTC

I am using Oracle SQL. I want to convert three columns to datetime in sql.
My data looks like:
DAY (DATE) HOUR (NUMBER) HALFHOUR (NUMBER)
21.04.22 11 22
21.04.22 11 23
21.04.22 12 24
21.04.22 12 25
21.04.22 13 26
21.04.22 13 27
....
I need to combine each row to the following specific format, in one column:
2022-04-21T13:30:00.00Z
Moreover, it should be converted from an utc time where data comes from (like UTC+3) to UTC+0 automatically.
How do I do this? I googled a lot, but cant do it.
Thanks :)
The solution to your problem is:
SELECT T1.*,
TO_CHAR(FROM_TZ(TO_TIMESTAMP(DAY||' '||HOUR||':'||HALFHOUR, 'DD.MM.RR HH24:MI'), 'Europe/Berlin') AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.ff2"Z"') as time_utc
FROM T1;
TO_TIMESTAMP:
TO_TIMESTAMP converts char of CHAR, VARCHAR2, NCHAR, or NVARCHAR2
datatype to a value of TIMESTAMP datatype.
Syntax is:
TO_TIMESTAMP( string1 [, format_mask] ['nlsparam'] )
FROM_TZ:
In Oracle Database, the FROM_TZ() function converts a timestamp value
and a time zone to a TIMESTAMP WITH TIME ZONE value. Pass the
timestamp value and the time zone as two separate arguments, and the
function returns them as a TIMESTAMP WITH TIME ZONE value.
Syntax is :
FROM_TZ(timestamp_value, time_zone_value)
time_zone_value all possible values an be found out using the below query:
SELECT * FROM V$TIMEZONE_NAMES;
The output generated using above two functions is the time in the germany time-zone and is converted to UTC time zone using the " AT TIME ZONE 'UTC' "
Then using TO_CHAR it is converted to the required format.
You can see the working sample example at the below link:
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=b030170a2c5536b4f80f1287bbfe4aca

Parse out Y-M-D from Y-M-D H-M-S UTC sql bigquery

I need to parse out '%Y%m%d' from the column in BigQuery. My data looks like this:
datetime_published
2000-09-25 13:28:15 UTC
2018-12-22 16:03:00 UTC
2018-05-04 03:05:00 UTC
I have tried the following:
SELECT PARSE_DATE('%Y%m%d', datetime_published) as date
The error message: No matching signature for function PARSE_DATE for argument types: STRING, TIMESTAMP. Supported signature: PARSE_DATE(STRING, STRING)
Desired output:
2000-09-25
Why not just convert to a date?
select date(datetime)
Note: This works for both datetime and timestamp values. These are different in BigQuery. You have a timestamp column which you have called datetime -- a bit of a misnomer.

bigquery standard sql error, invalid timestamp

I'm playing with some tables in bigquery and I receive this error:
Cannot return an invalid timestamp value of -62169990264000000 microseconds relative to the Unix epoch.
The range of valid timestamp values is [0001-01-1 00:00:00, 9999-12-31 23:59:59.999999]
Doing the query in legacy sql and sorting ascending, it displays as 0001-11-29 22:15:36 UTC
How does it get transformed into microseconds?
This is the query:
#standardSQL
SELECT
birthdate
FROM
X
WHERE
birthdate IS NOT NULL
ORDER BY
birthdate ASC
**strong text**Confirming , that in BigQuery Legacy SQL
SELECT USEC_TO_TIMESTAMP(-62169990264000000)
produces 0001-11-29 22:15:36 UTC timestamp
whereas in BigQuery Standard SQL
SELECT TIMESTAMP_MICROS(-62169990264000000)
produces error:
TIMESTAMP value is out of allowed range: from 0001-01-01 00:00:00.000000+00 to 9999-12-31 23:59:59.999999+00.
How does it get transformed in microseconds?
TIMESTAMP
You can describe TIMESTAMP data types as either UNIX timestamps or calendar datetimes. BigQuery stores TIMESTAMP data internally as a UNIX timestamp with microsecond precision.
See more about TIMESTAMP type
Midnight of January 1 of the year 0001 (the minimum possible timestamp value in standard SQL) is -62135596800000000 in microseconds relative to the UNIX epoch, which is greater than -62169990264000000. I don't have a good explanation for legacy SQL's behavior with that timestamp value, but you can read about some suggestions for dealing with it in standard SQL in this item on the issue tracker. We plan to add some content to the migration guide about this timestamp behavior in the future as well.

Oracle UTC Time

I'm trying to read an Oracle TIMESTAMP WITH TIMEZONE from a database in UTC-5 (NY) as UTC.
Oracle is driving me crazy:
SELECT
from_tz(MAX(TIMESTAMPWITHTIMEZONE),'UTC'),
SYS_EXTRACT_UTC(MAX(TIMESTAMPWITHTIMEZONE)),
SYS_EXTRACT_UTC(systimestamp),
SYSTIMESTAMP AT TIME ZONE 'UTC'
FROM TABLE
Results:
SYS_EXTRACT_UTC(systimestamp) gives me: 2013-02-20 14:59:04, which is probably right.
SYSTIMESTAMP AT TIME ZONE 'UTC' gives me: 2013-02-20 15:59:04 which is my own local Berlin - whatever
Now I want to have TIMESTAMPWITHTIMEZONE (TIMESTAMP(6)) as UTC
SYS_EXTRACT_UTC(MAX(TIMESTAMPWITHTIMEZONE)) is 2013-02-20 08:55:01
from_tz(MAX(TIMESTAMPWITHTIMEZONE),'UTC') is 2013-02-20 10:55:01
Srly. Oracle. I want UTC.
Which one is the right one? Or is there a better way?
The functions are different:
SYS_EXTRACT_UTC converts a TIMESTAMP WITH TIMEZONE to a TIMESTAMP (with inferred but absent timezone=UTC).
FROM_TZ converts a TIMESTAMP to a TIMESTAMP WITH TIMEZONE
These functions when applied to a single value will in general return a different result:
SQL> SELECT sys_extract_utc(localtimestamp) ext,
2 from_tz(localtimestamp, 'UTC') from_tz
3 FROM dual;
EXT FROM_TZ
--------------------- ------------------------
2013/02/20 15:34:24 2013/02/20 16:34:24 UTC
In the first case the TIMESTAMP is implicitly given the timezone of the server and then transformed into the equivalent timestamp at the UTC timezone. Note that in general you should stay away from implicit conversions.
In the second case there is no computation between timezones: the FROM_TZ function adds the geographical location to a point in time variable.
By the way there is something missing in your example: you can't apply the FROM_TZ function on a variable of type TIMESTAMP WITH TIMEZONE (tested on 9ir2 and 11ir2):
SQL> select from_tz(systimestamp, 'UTC') from dual;
select from_tz(systimestamp, 'UTC') from dual
ORA-00932: inconsistent datatypes:
expected TIMESTAMP got TIMESTAMP WITH TIME ZONE
Edit following comment:
In your case assuming that your column are of time TIMESTAMP, and knowing that they refer to the NY timezone, you could use the AT TIME ZONE expression to convert to UTC:
SQL> SELECT localtimestamp,
2 from_tz(localtimestamp, 'America/New_York') AT TIME ZONE 'UTC' utc
3 FROM dual;
LOCALTIMESTAMP UTC
--------------------- ------------------------
2013/02/20 17:09:09 2013/02/20 22:09:09 UTC
From Oracle 18c you could use TO_UTC_TIMESTAMP_TZ function:
The TO_UTC_TIMESTAMP_TZ function converts any valid ISO 8601 date represented as a string into a TIMESTAMP WITH TIMEZONE, which can optionally be used as input to the SYS_EXTRACT_UTC function.
SELECT TO_UTC_TIMESTAMP_TZ(col_name)
FROM tab_name;