Snowflake DB join on Timestamp field auto conversion issue - join

I have two tables both of which have a timestamp field [TIMESTAMP_TZ] and when I perform a join based on this timestamp field the plan in snowflake DB shows an auto conversion on these timestamps into LTZ. Ex
(TO_TIMESTAMP_LTZ(CAG.LOAD_DATE_UTC) = TO_TIMESTAMP_LTZ(PIT.CSAT_AGREEMENT_LDTS))
Any reason why this is happening?

TIMESTAMP_TZ means your timestamp is linked to a time zone and TIMESTAMP_LTZ is your local timezone. Probably the timezones of your two timestamps are different and thus Snowflake converts them automatically to your local timezone to match them correctly.

Related

TypeORM: Dates in SQLite Not Getting Returned Correctly

I'm using SQLIte3 v5.0.2 and TypeORM v0.2.38. I created a date column on a SQLIte table using date DATETIME DEFAULT CURRENT_TIMESTAMP.
When I search the database for rows between dates, it wasn't pickup up rows on the last day so I added a time to my BETWEEN query: WHERE date BETWEEN '2021-01-01 00:00:00' AND '2021-01-31 11:59:59' to include rows on last day.
As soon as I add the time part for the Between query for the date/time, it appears to load the field into entities using the local timezone. Without the time part it doesn't do this but also doesn't find the last days rows. I looked in the database and saw the date times are being stored with my local timezone (-7hrs) instead of UTC as I've seen is meant to be the case on several Github issues for TypeORM.
How can I ensure the dates are saved and loaded only as UTC so they don't change when I query rows in TypeORM? I'm considering writing a custom transformer for the entity field but if its supposed to be UTC by default then is this a bug or am I doing something wrong?

Converting Snowflake Database Timezone

I have a database that the timestamps are all in UTC format, but I need to convert, for just this one database, it over to CST for any (and all) timestamp fields.
There are 200 tables, so I don't have each table/field mapped that need to be updated. Is there a way to do this, without using
'''
convert_timezone
''' or
'''
dateadd
'''
on every query written?
The database instance is set to CST, but that database is in UTC.
You would need to write a stored proc that would read the ACCOUNT_USAGE.COLUMNS table, identify columns that have a date datatype and then construct SQL statements for each table that updated the values using CONVERT_TIMEZONE

Is there an intrinsic timezone for a date column in the database

I am using ruby on rails. When you save a column with type datetime then an intrinsic timezone is stored for the date and time. How is a column of type date stored and in particular is there any timezone associated with the date?
Active record tries to retrieve all stored dates as UTC, although you can configure it to use a local time:
http://guides.rubyonrails.org/configuring.html#configuring-active-record
config.active_record.default_timezone determines whether to use Time.local (if set to :local) or Time.utc (if set to :utc) when pulling dates and times from the database. The default is :utc.
Based on Garrett Motzner's comments, there is no intrinsic timezone stored with date column as opposed to a datetime column which does have a timezone associated with it. This means that if users have different timezones, then you will need to manually account for the timezone if using a date column. The alternative is to use a datetime column to store the date and process it to account for the fact that only a date is being stored.

Rails column type for moment.js formatted date and time

I am building a rails app, where the user picks up a date from a date picker and a time from the time picker. Both the date and time have been formatted using moment js to show the date and time in the following way:
moment().format('LL'); //January 23,2017
moment().format('LTS'); //1:17:54 PM
I read this answer with guidelines about selection of a proper column type.
Is there documentation for the Rails column types?
Ideally, I should be using :date, :time or :timestamp for this. But since the dates are formatted, should I be using :string instead?
Which would be the correct and appropriate column type to use in this situation?
If you want to store a time reference in your database you should use one of the types the database offers you. I'll explain this using MySQL (which is the one I have used the most) but the explanation should be similar in other database servers.
If you use a timestamp column you will be using just 4 bytes of storage, which is always a good new since it makes smaller indexes, uses less memory in temporal tables during the internal database operations and so on. However, timestamp has a smaller range than datetime so you will only be able to store values from year 1970 up to year 2038 more or less
If you use datetime you will be able to store a wider range (from year 1001 to year 9999) with the same precision (second). The bad consequence is that a higher range needs more memory, making it a bit slower.
There are some other differences between these two column types that don't fit in this answer, but you should keep an eye on before deciding.
If you use varchar, which is the default column type for text attributes in Ruby on Rails, you will be forced to convert from text to datetime and vice-versa every time you need to use that field. In addition, ordering or filtering on that column will be very inefficient because the database will need to convert all strings into dates before filtering or sorting, making it impossible to use indexes on that column.
If you need sub-second precision, you can use bigint to meet your requirements, as MySQL does not provide a date specific type for this purpose
In general, I recommend using timestamp if your application requirements fit the timestamp limitation. Otherwise, use datetime, but I strongly discourage you to use varchar for this purpose.
EDIT: Formatting
The way you store dates in database is completely different from the way you display it to the user. You can create a DateTime object using DateTime.new(year, month, day, hour, minute, second) and assign that object to your model. By the time you save it into database, ActiveRecord will be in charge of converting the DateTime object into the appropiate database format.
In order to display a value that is already stored in database in a specific format (in a view, API response, etc.) you can hava a look at other posts like this one.
You can have a timestamp column in your database, and then parse the request to a ruby datetime object like this:
d = Time.parse(params[:date])
t = Time.new(params[:time])
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
#now simply use dt to your datetime column
On Postgres you can save a ruby DateTime object straight into a postgres timestamp field, e.g
User.first.update_attribute('updated_at', dt )
Another option is to concatenate your date and time strings into one and then u can do a one-liner:
User.last.update_attribute('created_at', Time.parse('January 23,2017 1:17:54 PM'))
I'm pretty sure this will work on MySQL datetime or timestamp as well.
Credit to david grayson Ruby: combine Date and Time objects into a DateTime

SQLite DateTime columns accepting any value... normal?

I have an iOS app that takes use of SQLite. I use FireFox and the plugin SQLite Manager for managing the database.
Now I have a table like this:
CREATE TABLE "someTable" ("id" INTEGER NOT NULL , "timeOfEvent" DATETIME NOT NULL)
I am however able to input practically any value I want into the DateTime column like so:
INSERT INTO sometable (id, timeOfEvent) VALUES (1,'2012-99-99')
INSERT INTO sometable (id, timeOfEvent) VALUES (2,'yyyy-mm-dd')
...etc
Why is this possible?
As per the documentation: SQLite- Data Types
SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Thus SQLite relies on methods to convert the values. It doesn't have it's own data type to restrict date/time type.
SQLite is dynamic. From SQLite Query Language - CREATE TABLE
Unlike most SQL databases, SQLite does not restrict the type of data that may be inserted into a column based on the columns declared type. Instead, SQLite uses dynamic typing. The declared type of a column is used to determine the affinity of the column only.

Resources