Comparing UTC with local in Snowflake - snowflake-cloud-data-platform

I have a date column called actual_cargo_ready_date_local, it is of type TIMESTAMP_NTZ(9).
Next we're trying to compare a column with UTC values, say the column name is booked_at.
Is it correct to do the comparison as follows;
booked_at > actual_cargo_ready_date_local::timestamp_ntz
Essentially, my question is can we compare a column with values in UTC with timestamp column with values in local timezone.
And is it true that using the command actual_cargo_ready_date_local::timestamp_ntz coverts the actual_cargo_ready_date_local into UTC.
Thanks

TLDR: Use CONVERT_TIMEZONE.
If actual_cargo_ready_date_local and booked_at are both of type TIMESTAMP_NTZ, there is no notion of the "origin" timezone here at all, so the system can not automatically make the comparisons right.
Casting actual_cargo_ready_date_local::timestamp_ntz does not have any effect, as the datatype doesn't change.
However, if you know that actual_cargo_ready_date_local is in some timezone, let's say America/New_York, and booked_at is in UTC, you can use CONVERT_TIMEZONE to convert the times into UTC:
booked_at > CONVERT_TIMEZONE(actual_cargo_ready_date_local, 'America/New_York', 'UTC')

Related

Add timezone offset retroactivly to SQL Server datetime entries

We have our time saved without a timezone offset inside our SQL Server database. The time is actually Central Europe Standard Time but due to no timezone offset in the time string it is treated as UTC. This now creates a bunch of problems regarding daylight saving times.
My question would be: is there a way to retroactively convert the Time with offset to the correct CEST Time.
For example my time string in my database is '2022-10-30 02:00' and should be converted to '2022-10-30 00:00+2' as well as '2022-10-30 03:00' to '2022-10-30 01:00+1'.
There is an option to convert a datetime object to another timezone with "AT TIME ZONE" but this didn't help much due to the date objects being treated as UTC in the database, but we need to convert them to the UTC+[offset] format. Also due to the daylight saving time changing timezone offsets during the year, we can't subtract the timezone offsets with a set value.

Snowflake date_trunc to remove time from date

I have snowflake column which contains date in yyyy-mm-dd hh:MM:ss format.
I use the below function
date_trunc('DAY', '2019-09-23 12:33:25')
Output : 2019-09-23 00:00:00
Expected as per documentation : 2019-09-23
Is it a bug or is there any other way to remove the time component altogether ?
Depending on what you're wanting to do with the date, having a midnight time is fine.
If you really must get rid of it, this will work:
cast(date_trunc('DAY', '2019-09-23 12:33:25') as date)
date_trunc as the documentation say, truncates a timestamp to values on different grain. But the result is still a timestamp, thus the output format.
if you want just the truncated date, casting to date as cmcau mentions is a simple way to go. But if you are casting to date there is no need to truncate as they are the same value, thus '2019-09-23 12:33:25'::date should be all you need.
In certain environments like Mode Analytics, casting to date like some of the other answers mention still displays a 00:00:00 on the end. If this is the case and you are only using the date for display purposes, you can take your truncated date and cast it to varchar instead like this: '2019-09-23 12:33:25'::date::varchar
Note, I would only recommend this if the other answers are not working for you.

change the date in ssis package for XML file

I am working on SSIS in my XML file I have reading dates like 2013-08-02, 2013-08-4, 2013-08-05 but I have to change the data date to from last two days, What I mean is that the data date stamp should be changed to 2017-05-21,2017-05-22,2017-05-22.
what I was done is added a derived column in the SSIS package and changed the expression with GETDATE() in this case I am getting only today date, But I need to change data from last two days.
Can anyone help me?
Use the DATEADD function to add or subtract time from a date. In your Derived Column, use this in the Expression field:
DATEADD("d", -2, GETDATE())
Note that this does subtract the time value as well so if you need to convert to strictly date format (or time zone conversions) you will need additional code.

Passing dates to parameter in SSRS

In which format I should pass date field to parameter to be able to choose date picker insted of list?
My query returns date (date format) and I cast it in a different ways (yyyy-dd-MM, yyyy-MM-dd, dd-MM-yyyy, ...) in SSRS:
=Format(Fields!StartDate2.Value,"yyyy-dd-MM")
I use this field in parameter, but I always get error:
An error has occurred during report processing. (rsProcessingAborted)
The property ‘ValidValues’ of report parameter ‘STARTDATE’ doesn't
have the expected type. (rsParameterPropertyTypeMismatch)
When I just passing result of query (date format), I have list:
even If chose Date/Time:
Answer
The reason you are getting this problem is because the Language/Culture/Date Format on your environments are not similar.
SQL by DEFAULT uses en-US and your local pc uses your local Language/Culture/Date Format.
there is your problem, instead of converting the value of your dates to your local
Language/Culture/Date Format, convert it to en-US
"MM-dd-yyyy"
Answer explained
to put this in perspective you are sending a SQL server with the date format
"MM/dd/yyyy" the value "2017/16/03".
so the server thinks "this guy is telling me to search for the 2017th month, 16th day of the year 03"

Using AT TIME ZONE to get current time in specified time zone

I am trying to use the new AT TIME ZONE syntax in SQL Server 2016 and Azure SQL. I'm just trying to get the current time in London as a datetime, adjusted for daylight saving. At the time of running all of the commands below, the time in London was 3.27am.
The first step is to get a datetimeoffset, which I can successfully do as follows:
DECLARE #dto datetimeoffset
SET #dto = (SELECT GETUTCDATE() AT TIME ZONE 'GMT Standard Time')
SELECT #dto
This returns a value as I would expect:
2016-04-04 02:27:54.0200000 +01:00
Next, I want to convert that to a datetime, which is what my applications expect. I've tried three different approaches, none of which give me the result I'm looking for:
SELECT SWITCHOFFSET(#dto,'+00:00')
-- Returns 2016-04-04 01:27:54.0200000 +00:00
SELECT CONVERT(datetime, #dto)
-- Returns 2016-04-04 02:27:54.020
SELECT CONVERT(datetime2, #dto)
-- Returns 2016-04-04 02:27:54.0200000
I feel like I'm missing something obvious - is there an easy way to take a datetimeoffset and return just the date/time part at that offset?
The first line of your code contains the fault:
SELECT GETUTCDATE() AT TIME ZONE 'GMT Standard Time'
GETUTCDATE() returns a datetime, which has no time zone offset information. Thus as described in the MSDN documentation:
If inputdate is provided without offset information, the function applies the offset of the time zone assuming that inputdate value is provided in the target time zone.
So, even though you retrieved the UTC time, you erroneously asserted that the value was in London time (which is UTC+1 for daylight saving time at this date).
The easiest way to handle this is to just fetch the UTC time as a datetimeoffset to begin with.
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'GMT Standard Time'
This invokes the conversion functionality of AT TIME ZONE, which in the docs states:
If inputdate is provided as a datetimeoffset value, then AT TIME ZONE clause converts it into the target time zone using time zone conversion rules.
Consider that if your data actually comes from a datetime field somewhere, you might need to use both parts of the functionality, like this:
SELECT mydatetimefield AT TIME ZONE 'UTC' AT TIME ZONE 'GMT Standard Time'
The first call to AT TIME ZONE asserts the value is in UTC, giving a datetimeoffset to the second call, which converts it to London time.
The output of any of these is a datetimeoffset, which you can cast or convert to a datetime or datetime2 exactly as you showed in your original question. (Don't use switchoffset for this.)
Also, the Windows time zone identifier for London is always "GMT Standard Time". It is inclusive of both Greenwich Mean Time and British Summer Time, with the appropriate transitions between them. Do not try change it to "GMT Daylight Time" - that identifier doesn't exist. This is also covered in the timezone tag wiki, in the section on Windows time zones.
Since I was unable to find this anywhere else I thought I'd share. You can get the offset in minutes by using datepart (tz) with AT TIME ZONE.
datepart(tz,UTC_Date AT TIME ZONE 'Central Standard Time')
select dateadd(MINUTE,datepart(tz,cast('2018-07-02 17:54:41.537' as datetime) AT Time Zone 'Central Standard Time'),'2018-07-02 17:54:41.537') as CentralTime
returns
CentralTime
2018-07-02 12:54:41.537
I suggest you only store this as a string and qualify that it is a local time representation, otherwise the time SQL Server stores internally would be the wrong actual/physical time, if the server time is correct, but just not in the same time zone. It is why you cannot use convert to represent the same because you are actually changing the datetime value from the real time of occurrence and not just re-representing it i.e. Datetime is always stored as UTC, but entered and displayed in the timezone of the server, so if you enter a local time in a datetime field, the server interprets that time as the time in the server time zone and not the actual time of the event, which results in stored time navigation/deviation if the local time is not the same as the server> Should you then feed the same data to other systems in different time zones, they will have incorrect data and it can get messy. Store the right value in the datetime field and display it as you wish as a string.

Resources