Truncate datetimes by second for all queries, but keep milliseconds stored in Postgres - postgresql

I'm trying to find a way to tell Postgres to truncate all datetime columns so that they are displayed and filtered by seconds (ignoring milliseconds).
I'm aware of the
date_trunc('second', my_date_field)
method, but do not want to do that for all datetime fields in every select and where clause that mentions them. Dates in the where clause need to also capture records with the granularity of seconds.
Ideally, I'd avoid stripping milliseconds from the data when it is stored. But then again, maybe this is the best way. I'd really like to avoid that data migration.
I can imagine Postgres having some kind of runtime configuration like this:
SET DATE_TRUNC 'seconds';
similar to how timezones are configured, but of course that doesn't work and I'm unable to find anything else in the docs. Do I need to write my own Postgres extension? Did someone already write this?

Related

PostgreSQL: require explicit time zone on INSERT/UPDATE of timestamptz columns

I'm digging into how Postgres works and have decided that any date/time data in my database should be of datatype timestamptz.
The rules that govern how Postgres parses date/time information vary based on the server's timezone, the client session timezone, and/or the database timezone setting. I can't expect my developers to know all of this, so to avoid any ambiguity I would like to somehow procedurally require a timezone be specified in any INSERT or UPDATE to a timestamptz column, and for any UPDATES or INSERTS to fail when the input value for a timestamptz column doesn't explicity include a time zone. I've created a regex that I can use to match against the input value; I just don't know how to hook up the plumbing.
I first thought I could do this with a custom domain; however, it appears that the CHECK constraint on a domain is done after the input string has already been parsed, so that won't work. (By then, the server has already inferred the time zone for values where time zone wasn't explicitly included.)
I could use a custom data type, but that's a whole can of worms there and I'm not sure that doing so would preserve all of the operators and functions that would operate on the underlying timstamptz column.
I could use BEFORE INSERT and BEFORE UPDATE triggers, but doing so would require me to iterate over every column in the NEW record, determine its datatype, then check the value against a regex to ensure a time zone is specified.
Does the community have any ideas on how to accomplish this? I think the BEFORE INSERT/BEFORE UPDATE is likely the best place to do this work, but I don't know how to iterate over the new record and find the data type for each column.
Is there an easier way to accomplish this that I've missed?
I can't expect my developers to know all of this
I think that's your problem. If you want to use PostgreSQL and work with time zones, you need your developers to understand it.
It's all very simple: Only set the timezone parameter correctly for the client session, then everything will just work.

date time with timezone

The date/time strings we're sending over to pub/sub look like this:
2018-07-18T17:30:08Z
I created a data flow job to insert these into Big Query and it failed at insert.
Stripping out the "Z" at the end like this was successful:
2018-07-18T17:30:08
The problem is that Big Query seems to be interpreting this as a local time, and not UTC.
I've tried both of these ways to insert the time zone:
2018-07-18T17:30:08+00:00
2018-07-18T17:30:08+0000
Both are rejected.
What's the correct way to do this, or is there some other way I can force Big Query to interpret these times as UTC?

Postgres timestamp to date

I am building a map in CartoDB which uses Postgres. I'm simply trying to display my dates as: 10-16-2014 but, haven't been able to because Postgres includes an unneeded timestamp in every date column.
Should I alter the column to remove the timestamp or, is it simply a matter of a (correct) SELECT query? I can SELECT records from a date range no problem with:
SELECT * FROM mytable
WHERE myTableDate >= '2014-01-01' AND myTableDate < '2014-12-31'
However, my dates appear in my CartoDB maps as: 2014-10-16T00:00:00Z and I'm just trying to get the popups on my maps to read: 10-16-2014.
Any help would be appreciated - Thank you!
You are confusing storage with display.
Store a timestamp or date, depending on whethether you need time or not.
If you want formatted output, ask the database for formatted output with to_char, e.g.
SELECT col1, col2, to_char(col3, 'DD-MM-YY'), ... FROM ...;
See the PostgreSQL manual.
There is no way to set a user-specified date output format. Dates are always output in ISO format. If PostgreSQL let you specify other formats without changing the SQL query text it'd really confuse client drivers and applications that expect the date format the protocol specifies and get something entirely different.
You have two basic options.
1 Change the column from a timestamp to a date column.
2 Cast to date in your SQL query (i.e. mytimestamp::date works).
In general if this is a presentation issue, I don't usually think that is a good reason to muck around with the database structure. That's better handled by client-side processing or casting in an SQL query. On the other hand if the issue is a semantic one, then you may want to revisit your database structure.

UTC datetime offset

I need to get timestamps from Axapta-tables in TSQL, without timezone and / or daylight-bias-offsets for each time, eg from table JMGABSENCECALENDAR.
Taking this as initial approach, and regaring this, it works for current time. But reading data from the table referring to other timestamps, the solution provided in the second link doesn't get the information about daylight to the specified time.
For example:
I add an absence for today ( 2012-01-07 ).
Now, using SSMS, reading this dataset leads to
starttime = 2013-01-06 23:00:00.000
and endtime = 2013-01-07 23:00:00.000
That's ok, and I can use
DECLARE #UTCOffset SMALLINT
EXEC master..xp_regread
'HKEY_LOCAL_MACHINE',
'SYSTEM\CurrentControlSet\Control\TimeZoneInformation',
'ActiveTimeBias',
#UTCOffset OUTPUT
SELECT DATEADD(MINUTE, #UTCOffset, GETDATE()) AS UTCTime
to remove offset. This works fine on actual dates, but what's the right way to remove offset for past or future times, eg 2012-07-01 ?
Here, the offset is 120 minutes, because of summertime. Reading Reg-Value only returns current offset.
The task has to be solved in TSQL 2008.
I had a same problem, but it was in a complete different setting. I had nothing to do with axapta.
However, i had the problem that i had to know the UTC offset of different times. The tricky part here is the fact that different countries use a different approach towards daylight saving times, and therefor a difference in the offset may occur for different countries at the same time.
What i did was to create a lookup table where i put in the dates that UTC offsets change, these are known dates. I gave it an offset column so i could easily look up the offset that i needed for a certain date, using the between operator.
It worked for me, maybe this solution can provide you something?
Ps. You don't have to lookup the UTC date offset from out of the registry. Using the function getutcdate() will give you the same ;) Using that inside a DATADD makes it a little more readable ;)
Have fun and i hope i could contribute to your problem...
Just because the daylight savings switch dates change from year to year and state to state, your only viable option is a lookup table.
You can find the data for example here http://www.timeanddate.com/time/dst/2013a.html
However, you might not have to maintain that list yourself. timeanddate.com has a calculator on their site. Others offer similar services. You could look for a public API and then use a few lines of CLR code to call that API from your database.
Or you could use such a service to maintain your own copy of that data. Having your own lookup table will be by far the fastest solution.

Can Perl DBIx::Class override the way a column is retrieved from the database?

I have never used DBIx::Class until today, so I'm completely new at it.
I'm not sure if this is possible or not, but basically I have a table in my SQLite database that has a timestamp column in it. The default value for the timestamp column is "CURRENT_TIMESTAMP". SQLite stores this in the GMT timezone, but my server is in the CDT timeszone.
My SQLite query to get the timestamp in the correct timezone is this:
select datetime(timestamp, 'localtime') from mytable where id=1;
I am wondering if it is possible in my DBIx schema for "MyTable" to force it to apply the datetime function every time it is retrieving the "timestamp" field from the database?
In the cookbook it looks like it is possible to do this when using the ->search() function, but I am wondering if it's possible to make it so if I'm using search(), find(), all(), find_or_new(), or any function that will pull this column from the database, it will apply the datetime() SQLite function to it?
DBIx::Class seems to have great documentation - I think I'm just so new at it I'm not finding the right places/things to search for.
Thanks in advance!
I've used InflateColumn::DateTime in this way and with a timestamp, and I can confirm it works, but I wonder if you have this backward.
If your column is in UTC, mark the column UTC, and then it should be a UTC time when you load it. Then when you set_timezone on the DateTime (presumably that would be an output issue - it's at output that you care it's locally zoned) you can set it to local time and it will make the necessary adjustment.