Is there a way to convert ISO 8601 to date format in BigQuery? - google-bigquery

I have input from Amazon Alexa in the format of ISO 8601 and was wandering if I needed to do a whole bunch of string substrings & transforms to make it into a BigQuery Timestamp format, or is there some function that does it?
I also understand that it is hard to turn 2015-W49 into a date, but thought I would ask.
references:
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/built-in-intent-ref/slot-type-reference#date
https://en.wikipedia.org/wiki/ISO_8601#Dates
https://code.google.com/p/google-bigquery/issues/detail?id=208

This can be done via the function PARSE_DATE as detailed here: https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#parse_date
In BigQuery Standard SQL:
SELECT DATE_ADD(PARSE_DATE('%Y', SUBSTR('2015-W49',0,4)), INTERVAL CAST(SUBSTR('2015-W49',7,2) as INT64)-1 WEEK) as parsed;

I would expect below result of such conversion, which is first day of the respective week, which should be respectively :
Week Date in ISO 8601 First Day of the week
2015-W01 2014-12-28
2015-W02 2015-01-04
2015-W49 2015-11-29
You can verify above at http://www.enpicbcmed.eu/calendar/2015-W01 for example
I think below returns correct result
#standardSQL
WITH data AS (
SELECT '2015-W01' AS dt UNION ALL
SELECT '2015-W02' AS dt UNION ALL
SELECT '2015-W49' AS dt
)
SELECT
dt,
DATE_ADD(PARSE_DATE("%Y-W%W", dt),
INTERVAL 7 * CAST(SUBSTR(dt,-2,2) AS INT64) - 6 -
EXTRACT (DAYOFWEEK FROM PARSE_DATE("%Y-W%W", dt)) DAY
) as d
FROM data
ORDER BY dt

This worked for me:
DATE_ADD(
DATE_TRUNC(PARSE_DATE('%Y-%m-%d', CAST(date_close AS STRING)), ISOYEAR),
INTERVAL EXTRACT(WEEK FROM date_close) - 1 WEEK
)

Related

How can I convert a string quarter year to a timestamp in Databricks SQL

In Databricks SQL, how can I convert a date in string format "2021Q2" to a timestamp with the last day of that quarter?
select
to_timestamp(
last_day(
to_date(
(left('2021Q4',4)||'-'||int(right('2021Q4',1)*3))||'-'||'1')))
from
my_table
It is a pity that Q is not working in formatting from string to date object (it is working only in reverse) - parsing Q with to_date(date, "YYYY'QQ") sadly will not work.
According to https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html:
Symbols of ‘E’, ‘F’, ‘q’ and ‘Q’ can only be used for datetime formatting, e.g. date_format. They are not allowed used for datetime parsing, e.g. to_timestamp.
Because of that we have to separate quarter and multiple by 4. Than convert it to date object (parse_ and take last_date of the month:
SELECT
last_day(
to_date(
concat(left("2021Q4", 4), int(right("2021Q4", 1))*3),
"yyyyMM")
) as last_day_of_quarter
Simple way :
select to_timestamp(last_day(concat('2021','-',0,4*3,'-01'))) as last_date_queter
Logic :
calculate the last month of quarter by using multiple with 3. example 4th quarter's last month calculated 12 (4*3)
concat (year,'-',-01) so that we can get the first day of respective month 2021-12-01
last_day we can use last date of the given date month.
finally , we can convert the date into timestamp to_timestamp

How to Convert Year-Week to Year-Month-Day in SQL?

Is there an efficient way or function to convert the week of the year to a datetime object? For example, if I had "2018-03", how would I be able to convert it to "2018-01-21"? (The third week of the year would correspond to the third week of the year, January 21st).
Any help is appreciated. Thank you in advance!
consider below as an option
select year_week,
date_add(
date(cast(split(year_week, '-')[offset(0)] as int64), 1, 1),
interval cast(split(year_week, '-')[offset(1)] as int64) * 7 - 1 day
) date
from data
if applied to sample data in your question - output is

Extraxt date from ISO Week (201905) BigQuery

I need to extract date of Sunday from it's ISO Week number: i.e. 201905
It needs to be in #standardSQL as it's going to be scheduled with scripts that don't support legacy.
I tried adjust working formula from Google Sheets but can't figure it out.
The original formula from Google Sheets:
TO_TEXT (
(DATE(LEFT(Week_ISO,4),1,1)
- (WEEKDAY(DATE(LEFT(Week_ISO,4),1,1))-2)
+ (RIGHT(Week_ISO,2)-1)*7)
+6)
From my reading of the documentation, this should work:
PARSE_DATE('%G%V', isoyyyymm)
But it doesn't.
So, here is an alternative:
SELECT DATE_ADD(DATE_TRUNC(PARSE_DATE('%Y%m%d', CONCAT(substr(isoyyyyww, 1, 4), '0601')),
isoyear
),
INTERVAL CAST(substr(isoyyyyww, -2) as int64) WEEK
)
FROM (SELECT '200506' as isoyyyyww);
The idea here is the following:
Convert your yyyyww format into a date in the middle of the year.
Truncate the date to the beginning of the ISO year.
Add back the appropriate number of weeks.
You can adapt this if your value is a number rather than a string.
The other option for me was to just not change to ISOWEEK. The iso week loses the year information anyway. Instead I just floored all dates to the first day of the ISOWEEK.
DATE_ADD(
LAST_DAY(DATETIME(date), ISOWEEK),
INTERVAL
-6
DAY) as login_week
It seems your proposition is not totally right. For instance, it's not working for the week 200101. With your formula, the answer is 2001-01-08.
Here is my suggestion :
SELECT DATE_ADD(DATE_TRUNC(PARSE_DATE('%Y%m%d', CONCAT(substr(isoyyyyww, 1, 4), '0104')),isoyear), INTERVAL CAST(substr(isoyyyyww, -2) as int64)-1 WEEK)
FROM (SELECT '200506' as isoyyyyww);

BigQuery convert String to Date

In my dataset, one column called timestamp was created with datatype as String.
It contains values like:
2018-05-30T12:56:27:487+0200
I want to construct a query where I can fetch all column from the dataset table based on the date in 'YYYY-MM-DD' format.
I want to use it in where clause with DATE Range between.
Can you guide?
Thank you.
convert String to Date
Below example for BigQuery Standard SQL
#standardSQL
WITH `project.dataset.table` AS (
SELECT '2018-05-30T12:56:27.487+0200' ts UNION ALL
SELECT '2018-05-30T01:56:27.487+0200'
)
SELECT ts AS ts_as_string,
PARSE_TIMESTAMP('%FT%H:%M:%E3S%z', ts) ts_as_timestamp,
DATE(PARSE_TIMESTAMP('%FT%H:%M:%E3S%z', ts)) ts_as_date
FROM `project.dataset.table`
with result
ts_as_string ts_as_timestamp ts_as_date
2018-05-30T12:56:27.487+0200 2018-05-30 10:56:27.487 UTC 2018-05-30
2018-05-30T01:56:27.487+0200 2018-05-29 23:56:27.487 UTC 2018-05-29
As you can see - first i am parsing timestamp out of the string - this is important part - this is where you can take timezone into account (see difference in dates in the result 2018-05-29 vs. 2018-05-29). Then you can get Date out of TIMESTAMP
I want to use it in where clause with DATE Range between.
So, now you can use below in your WHERE clause
WHERE DATE(PARSE_TIMESTAMP('%FT%H:%M:%E3S%z', ts)) BETWEEN date1 AND date2
Update
You can use below to avoid dealing with "wrong" format
PARSE_DATE('%F', SUBSTR(ts, 1, 10))
In case if you need to account for timezone - you can use below (which fix : to . before applying PARSE_TIMESTAMP)
DATE(PARSE_TIMESTAMP('%FT%H:%M:%E3S%z', FORMAT('%s.%s', SUBSTR(ts, 1, 19), SUBSTR(ts, 21, 8))))
If you want the date in the same timezone represented, then the simplest method is to use string operations and convert to a date:
select PARSE_DATE('%Y-%m-%d', SUBSTR('2018-05-30T12:56:27:487+0200', 1, 10))

how do I convert mmyy to last day of month in netezza

One of my column needs to be transformed into a date field. It contains a value that gives the YYMM and it should be translated into the last day of that month:
For example, 1312 should become 12/31/2013.
I have tried various last_day, to_char functions but not able to convert 1312 in a date format. Please help !!
Netezza is based on Postgres, so maybe the Postgres method will work. Here is Postgres code that works (see here):
select to_date('1312'||'01', 'YYMMDD') + interval '1 month' - interval '1 day'
I would first convert the number to a date, then add 1 month and subtract 1 day.
select add_months(to_date(1312, 'yymm'), 1) - 1 as the_date