SQL insert unix timestamp with milliseconds - date

Can unix timestamps contain the milliseconds value of the time?
If so, using SQL Server 2008 R2:
CREATE TABLE [dbo].[my_table_calls_log]
(
[id] [bigint] IDENTITY(1,1) NOT NULL,
[requestdate] [bigint] NULL,
[partycode] [bigint] NULL,
CONSTRAINT [PK_my_table_calls_log]
PRIMARY KEY CLUSTERED ([id] ASC)
)
The following select gives me the current date and time with milliseconds:
SELECT CONVERT(VARCHAR,SYSDATETIME(),121);
Example:
2015-09-11 13:29:02.8239061
How do I convert that long YYYY-MM-DD HH:MM:SS.MS date/time value into a unix timestamp so that I can insert it using something like:
DECLARE #UnixDate AS bigint;
SET #UnixDate = "the unix timestamp equivalent of SELECT CONVERT(VARCHAR,SYSDATETIME(),121);"
INSERT INTO my_table_calls_log (requestdate,partycode)
VALUES (#UnixDate,123);

Standard unix timestamps are 32-bit signed integers with a precision of 1 second (see here), that said there is certainly nothing invalid about using a 64-bit integer and using a precision of milliseconds if you so choose (so long as you are certain that all code that will use/consume that timestamp value is aware of that constraint). Most standard unix timestamp libraries assume it is a 1 second precision, and if you pass a 64-bit signed integer instead of a 32-bit integer that still holds and the assumption is the user is just planning for a longer life of the timestamp (i.e. to track date/time values past January 19, 2038, which is the date a 32-bit based unix timestamp will stop working at some point from the default epoch due to an overflow).
Unix timestamps also generally assume a base epoch of '1970-01-01 00:00:00', so using that assumption you can convert a standard SQL Server datetime value to a unixtimestamp using something like this:
select datediff(second, '1970-01-01T00:00:00.000', sysdatetime());
If you want that to be millisecond based, it becomes a bit more complex as the datediff function in SQL Server is 32-bit integer based (i.e. an int data type) and the difference between the default epoch and the current date/time in milliseconds exceeds the upper-bound of that type, so we have to get a little creative, here is one option (which I tend to use wrapped in a function):
declare #start datetime2 = '1970-01-01T00:00:00.000',
#end datetime2 = sysdatetime(),
#ms_in_day bigint = 60 * 60 * 24 * 1000;
select (#ms_in_day * datediff(day, #start, #end)) - datediff(millisecond, #end, cast(#end as date));
In each of these examples, if you have a varchar/character based date/time value, simply insert directly into the script in place of the sysdatetime() function I used.

Related

Calculate the difference between two hours on PostgreSQL 9.4

Given a table as the following:
create table meetings(
id integer primary key,
start_time varchar,
end_time varchar
)
Considering that the string stored in this table follow the format 'HH:MM' and have a 24 hours format, is there a command on PostgreSQL 9.4 that I can cast fields to time, calculate the difference between them, and return a single result of the counting of full hours available?
e.g: start_time: '08:00' - end_time: '12:00'
Result must be 4.
In your particular case, assuming that you are working with clock values (both of them belonging to the same day), I would guess you can do this
(clock_to::time - clock_from::time) as duration
Allow me to leave you a ready to run example:
with cte as (
select '4:00'::varchar as clock_from, '14:00'::varchar as clock_to
)
select (clock_to::time - clock_from::time) as duration
from cte

PostgreSQL now() function not returning time

When inserting now() in a table, the written value only contains the date (e.g. 2017-12-20), but not the date and time as specified in the documentation.
See this SQLfiddle.
create table timetest (
id serial primary key,
mydate date
);
insert into timetest (mydate) values (
now());
Is there some specific command that should be passed to either write or retrieve also the time information?
You created mydate date as a date type column. date only represents the date fraction (unsurprisingly).
If you need both date and time use timestamp type instead.
References:
https://www.postgresql.org/docs/current/static/datatype-datetime.html

how to store 13 digit timestamp in cassandra

I want to create this table but I want to save datetime in 13 digit timestamp format e.g 1424109603234
create table data (
datetime timestamp,
id text,
type text,
body text
primary key (id, type, datetime)
)
is the datatype of datetime correct? how should I insert data, in any specific function like toTimestamp(now())??
datatype for datetime is correct.
Values for the timestamp type are encoded as 64-bit signed integers representing a number of milliseconds since the standard base time known as the epoch: January 1 1970 at 00:00:00 GMT. (For more detail refer to https://docs.datastax.com/en/cql/3.3/cql/cql_reference/timestamp_type_r.html
)
Now from your function you need to get the epoch timestamp and then convert it to milliseconds( There are lot of different codes to do that) and then push the converted time stamp (signed long long) to cassandra.

Convert bigint data type to timestamp (and subsequently to date) in redshift

I need to convert the value stored in a bigint column to a date field. The first step of the conversion involves converting it to timestamp, and subsequently use the TRUNC method to convert this column to a date value.
However, my query is failing while converting the bigint value to timestamp.
The error that I'm getting is:-
Amazon Invalid operation: cannot cast type bigint to timestamp without time zone;
The query I'm trying for now is something like this:-
select ts::timestamp from events limit 1;
I was able to avoid the time zone error by using the method described in this thread: https://stackoverflow.com/a/36399361
My dates are based on epochs, and I was able to do the following:
SELECT
(TIMESTAMP 'epoch' + contract_start_date * INTERVAL '1 Second ')
FROM
table_name
SELECT TIMESTAMP 'epoch' + {column of bigint}/1000 * INTERVAL '1 second' as adate FROM tbl
If you are starting with a POSIX timestamp, and trying to get a timezone aware datetime value, you will need to supply a timezone - even if you later want to truncate the time part away. I'm not familiar with redshift, but perhaps there is a way to specify you mean UTC.

Default timestamp format and fractional seconds

I'm trying to format the timestamps in my Postgres database to a certain format:
YYYY-MM-DD HH24:MI:SS
By doing:
update myTable set tds = to_char(tds, 'YYYY-MM-DD HH24:MI:SS')::timestamp;
I managed to set all the previously stored tds to this format. However, any newly added entry goes back to: YYYY-MM-DD HH24:MI:SS.MS since the default is set to now().
How do I change this so that newly added entries also have the format: YYYY-MM-DD HH24:MI:SS?
There is no format stored in a timestamp type. You can set its default to a timestamp truncated to the second at creation time
create table t (
tds timestamp default date_trunc('second', now())
)
Or alter the table
alter table t
alter column tds
set default date_trunc('second', now());
insert into t values (default);
INSERT 0 1
select * from t;
tds
---------------------
2014-03-11 19:24:11
If you just don't want to show the milliseconds part format the output
select to_char(now(), 'YYYY-MM-DD HH24:MI:SS');
to_char
---------------------
2014-03-11 19:39:40
The types timestamp or timestamptz optionally take a precision modifier p: timestamp(p).
To round to full seconds, set the default to:
now()::timestamp(0)
or:
now()::timestamptz(0)
Standard SQL functions CURRENT_TIMESTAMP (returns timestamptz) or LOCALTIMESTAMP (returns timestamp) allow the same precision modifier:
CURRENT_TIMESTAMP(0)
LOCALTIMESTAMP(0)
That's a bit shorter than calling date_trunc() - which truncates fractional seconds (may be what you really want!)
date_trunc('second', now())
Store timestamps as timestamptz (or timestamp), not as character type.
Finally, to make sure that ...
newly added entries also have the format: YYYY-MM-DD HH24:MI:SS
you could define your column as type timestamptz(0). This covers all values entered into that column, not just the default. But the rounding may introduce timestamps up to half a second in the future. If that can be an issue in any way, rather use date_trunc().
See #Clodoaldo's answer for instructions on to_char() and how to ALTER TABLE.
This related answer for in-depth information on timestamps and time zone handling:
Ignoring time zones altogether in Rails and PostgreSQL