Convert DATETIME to Unix Epoch in Informix - sql

I have a DATETIME column:
SELECT mytime FROM mytable;
mytime
--------------------
1/6/2013 10:41:41 PM
I would like to write a SQL statement that returns the time in Unix Time format (seconds since Unix Epoch - 01/01/1970 00:00:00) as INTEGER. I have tried to use DATEDIFF and CAST but no luck. This is Informix database.

Assuming that the mytime column is a DATETIME YEAR TO SECOND column (despite the formatting shown in the question), then the following stored procedure does the job. It has more comment than procedure, but the comments explain what it is doing.
{
# "#(#)$Id: tounixtime.spl,v 1.6 2002/09/25 18:10:48 jleffler Exp $"
#
# Stored procedure TO_UNIX_TIME written by Jonathan Leffler (previously
# jleffler#informix.com and now jleffler#us.ibm.com). Includes fix for
# bug reported by Tsutomu Ogiwara <Tsutomu.Ogiwara#ctc-g.co.jp> on
# 2001-07-13. Previous version used DATETIME(0) SECOND TO SECOND
# instead of DATETIME(0:0:0) HOUR TO SECOND, and when the calculation
# extended the shorter constant to DATETIME HOUR TO SECOND, it added the
# current hour and minute fields, as documented in the Informix Guide to
# SQL: Syntax manual under EXTEND in the section on 'Expression'.
# Amended 2002-08-23 to handle 'eternity' and annotated more thoroughly.
# Amended 2002-09-25 to handle fractional seconds, as companion to the
# new stored procedure FROM_UNIX_TIME().
#
# If you run this procedure with no arguments (use the default), you
# need to worry about the time zone the database server is using because
# the value of CURRENT is determined by that, and you need to compensate
# for it if you are using a different time zone.
#
# Note that this version works for dates after 2001-09-09 when the
# interval between 1970-01-01 00:00:00+00:00 and current exceeds the
# range of INTERVAL SECOND(9) TO SECOND. Returning DECIMAL(18,5) allows
# it to work for all valid datetime values including fractional seconds.
# In the UTC time zone, the 'Unix time' of 9999-12-31 23:59:59 is
# 253402300799 (12 digits); the equivalent for 0001-01-01 00:00:00 is
# -62135596800 (11 digits). Both these values are unrepresentable in
# 32-bit integers, of course, so most Unix systems won't handle this
# range, and the so-called 'Proleptic Gregorian Calendar' used to
# calculate the dates ignores locale-dependent details such as the loss
# of days that occurred during the switch between the Julian and
# Gregorian calendar, but those are minutiae that most people can ignore
# most of the time.
}
CREATE PROCEDURE to_unix_time(d DATETIME YEAR TO FRACTION(5)
DEFAULT CURRENT YEAR TO FRACTION(5))
RETURNING DECIMAL(18,5);
DEFINE n DECIMAL(18,5);
DEFINE i1 INTERVAL DAY(9) TO DAY;
DEFINE i2 INTERVAL SECOND(6) TO FRACTION(5);
DEFINE s1 CHAR(15);
DEFINE s2 CHAR(15);
LET i1 = EXTEND(d, YEAR TO DAY) - DATETIME(1970-01-01) YEAR TO DAY;
LET s1 = i1;
LET i2 = EXTEND(d, HOUR TO FRACTION(5)) -
DATETIME(00:00:00.00000) HOUR TO FRACTION(5);
LET s2 = i2;
LET n = s1 * (24 * 60 * 60) + s2;
RETURN n;
END PROCEDURE;

Function dbinfo('utc_current') returns epoch time (number of seconds since 1970-01-01 00:00:00 UTC).

Related

get today data from room database

get dates data from room database
i have created task db class as below
#ColumnInfo(name = "task_start_date") var taskStartDate: Date?,
#ColumnInfo(name = "task_end_date") var taskEndDate: Date?,
#ColumnInfo(name = "task_never_end") var taskNeverEnd: Boolean?
#PrimaryKey
var tid: Long?,
#ColumnInfo(name = "task_title") var TaskTitle: String?
I do insert data with below function
fun getTodayDate(): Date {
val calendar = Calendar.getInstance()
return GregorianCalendar(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE),
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND)
).time
}
fetching data with below codes and params todayDate = above functio getTodayDate()
#Query("select * from task where task_start_date =:todayDate ")
fun getTodayTask(todayDate: Date): List<Task>
with above implementation I m getting 0 result
I assume room is converting date to long and stores and also compare with long value so this thing never gonna match
so can u please help me out how to get task that only matched dates not time
example
I have inserted data for 11-09-2022 12:00:00 PM,11-09-2022 1:00:00 PM,11-09-2022 2:00:00 PM,11-09-2022 3:00:00 PM,11-09-2022 4:00:00 PM in the form of Date object not string.
now I want to fetch all task that match only date like 11-09-2022 not time
Converter
class TimestampConverter {
#TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
#TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time
}}
I believe that java times when converted to long include milliseconds so you need to strip of the milliseconds,seconds,minutes and hours.
You can divide both sides of the argument by 1000 (milliseconds) * 60 (seconds per minute) * 60 (minutes per hour) * 24 (hours per day) (i.e. 86,400,000 milliseconds per day) and this will strip of the time and the comparison will be at the date level.
So try:-
#Query("select * from task where task_start_date / 86400000 =:todayDate / 86400000 ")
Regarding the comment:-
how could this possible ? ex : I got milliseconds 1662899658575 and divide by 86400000. so result would be 19246.5238261.
Here is a demonstration that shows/explains using SQLite (which room is a wrapper around).
DROP TABLE IF EXISTS example;
CREATE TABLE IF NOT EXISTS example (timestamp);
INSERT INTO example VALUES(1662899658575);
SELECT
timestamp, /* The actual stored value */
strftime('%Y-%m-%d %H:%M:%S',timestamp/1000,'unixepoch') AS date, /* Using SQLite strftime function to extract the exact date time (less milliseconds) */
timestamp / (24 * 60 * 60 * 1000) AS `daysSince1:1:1970`, /* the number of days since 1/1/1970 (based upon the unix date/time) i.e. the date part only*/
(timestamp / (86400000 /* drop millisecs*/ * 365 /* drop years*/)) + 1970 /* add to start */ AS year /* The year factoring in unix datetime starting 1/1/1970 */
FROM example
;
DROP TABLE IF EXISTS example; /* Cleanup Environment*/
When run the columns output are:-
As can be seen
- 1662899658575 / 86400000 = 19246 which equates to the date as it is the number of days since 1/1/1970 and thus represents the date 2022-09-11 according to unix datetime
You may be interested in:-
In computing, Unix time (also known as Epoch time, Posix time,1 seconds since the Epoch,[2] Unix timestamp or UNIX Epoch time[3]) is a system for describing a point in time. It is the number of seconds that have elapsed since the Unix epoch, excluding leap seconds. The Unix epoch is 00:00:00 UTC on 1 January 1970.
Unix time is not a true representation of UTC, because a leap second and the second before it have the same Unix time (or after it, implementation dependent). Put differently, every day in Unix time contains exactly 86400 seconds;[2] no seconds added to or subtracted from the day as a result of positive or negative leap seconds.
Unix time originally appeared as the system time of Unix, but is now used widely in computing, for example by filesystems; some Python language library functions handle Unix time.[4]
https://en.wikipedia.org/wiki/Unix_time
https://www.sqlite.org/lang_datefunc.html

How to subtract hours and minutes from each other in PostgreSQL

I have two fields dateTS and closingTime.
dateTS is a normal timestamp field (e.g. 2019-07-13 22:31:10.000000)
closingTime is a HH:MM format of when a store closes (e.g. 23:00)
I need a PostgreSQL query to subtract the two field and get the number of minutes difference between them.
Using the examples given above the difference between the two fields would be 28 minutes
So far I've tried different variations of the datediff function, but it won't work.
My guess is I either have to
a. generate a fake timestamp for closingTime which is the same day as the dateTs field and subtract the 2 timestamps.
or
b. convert the hour/minutes of both field to a float and subtract the two values to get the hours difference and convert that to minutes
You can just subtract them by converting the timestamp to a time:
select closingtime - datets::time
from your_table;
That will give you an interval as the result.
To convert that to minutes you can get the number of seconds and divide it by 60:
select (extract epoch from closingtime - datets::time) / 60
from your_table;
Cast your closing time to an interval and the timestamp to time and then subtract the two. By casting the timestamp to time you are effectively discarding the date part. You can the subtract one from the other to generate the difference as an interval.
select closingTime::interval - dateTS::time...
e.g.:
# select '23:00'::interval - now()::time;
?column?
-----------------
05:31:00.031141
(1 row)
If needed you can then convert the interval to minutes:
# select extract(epoch from ('23:00'::interval - now()::time)) / 60;
?column?
------------------
327.435313083333
(1 row)

Converting only time to unixtimestamp in Hive

I have a column eventtime that only stores the time of day as string. Eg:
0445AM - means 04:45 AM. I am using the below query to convert to UNIX timestamp.
select unix_timestamp(eventtime,'hhmmaa'),eventtime from data_raw limit 10;
This seems to work fine for test data. I always thought unixtimestamp is a combination of date and time while here I only have the time. My question is what date does it consider while executing the above function? The timestamps seem to be quite small.
Unix timestamp is the bigint number of seconds from Unix epoch (1970-01-01 00:00:00 UTC). The unix time stamp is a way to track time as a running total of seconds.
select unix_timestamp('0445AM','hhmmaa') as unixtimestamp
Returns
17100
And this is exactly 4hrs, 45min converted to seconds.
select 4*60*60 + 45*60
returns 17100
And to convert it back use from_unixtime function
select from_unixtime (17100,'hhmmaa')
returns:
0445AM
If you convert using format including date, you will see it assumes the date is 1970-01-01
select from_unixtime (17100,'yyyy-MM-dd hhmmaa')
returns:
1970-01-01 0445AM
See Hive functions dosc here.
Also there is very useful site about Unix timestamp

SQL : How sysdate minus a value works?

I found below code in my existing project.
select * from mytable where SomeColumn_date >= trunc(sysdate)-.25/24;
Sample value for SomeColumn_date is 22-JUN-17 05:46:55
How does SomeColumn_date >= trunc(sysdate)-.25/24 work on Date data type?
Different database engines allow different operations to be applied to date data types. For the most part, an operation of <Date Value> +/- 1 will add or subtract one day to that date value. This is syntactically equivalent to the dateadd function when using days.
In your example here, the -.25/24 resolves to the number equivalent of -15 minutes, which is then subtracted from your date value.
It is essentially a much less readable version of datedd(min,-15,<Date Value>).
From the documentation of TRUNC (I'm guessing you are using Oracle):
The TRUNC (date) function returns date with the time portion of the day truncated to the unit specified by the format model fmt. [...] If you omit fmt, then date is truncated to the nearest day.
The result of trunc(sysdate) would be the present date without the time component. Now .25/24 (actually meaning 0.25/24) is substracted from that. If you substract a date using - the operand is always in days. 0.25/24 would be a form to express a quarter of an hour.
So trunc(sysdate)-.25/24 would result in yesterday 23:45.
Ok so 2 things are happening here:
trunk(date,fmt)
The TRUNC (date) function returns date with the time portion of the day truncated to the unit specified by the format model fmt. If you omit fmt, then date is truncated to the nearest day.
So if you have suppose 22-JUN-17 05:46:55 you get 22-JUN-17. Since you don't have the fmt
DATETIME - .25/24 implies .25 hours before your current Date time.
But since you have only DATE all it does is .25 hours before todays 12:00 AM i.e yesterdays 11:45PM
SomeColumn_date >= trunc(sysdate)-.25/24
So suppose if its 22-JUN-2017 right now the date is compared to 21-JUN-2017 11:45 PM
NOTE: - is for before current time, + is for after the current time

convert time in epoch time format

Code:
TBuf<50> TimeDesc;
TBuf <50> singleLog;
TTime time = event.Time();
_LIT(KTimeFormat,"%I%:1%T%:1%S %B");
RTz tzServer;
User::LeaveIfError(tzServer.Connect());
CleanupClosePushL(tzServer);
CTzConverter* tzConverter = CTzConverter::NewL(tzServer);
CleanupStack::PushL(tzConverter);
tzConverter->ConvertToLocalTime(time);
time.FormatL(TimeDesc,KTimeFormat);
singleLog.Append(TimeDesc);
singleLog.Append('|');
How to convert this time in epoch time format?
I found this function which takes a Unix Epoch timestamp and returns a TTime:
// This function converts a Unix Epoch timestamp to a TTime
TTime UnixToEpocTimeL(TUint32 aTimestamp)
{
// define the start of the Unix Epoch as beginning of Jan 1, 1970
_LIT(KUnixEpoch, "19700000:");
// Create a new time variable, and give it the starting value of Jan 1, 1970
TTime time;
User::LeaveIfError(time.Set(KUnixEpoch));
// The timestamp is the number of seconds since Jan 1, 1970
// Add the number of seconds in the timestamp to start date.
TTimeIntervalSeconds secs(aTimeStamp);
time += secs;
// the variable 'time' now contains the requested datetime
return time;
}
http://discussion.forum.nokia.com/forum/showthread.php?t=110494
UPDATE: I don't know much about this (nor do I have any way of testing it here!) but I have tried to add detailed comments explaining how I think it works. You can either add something similar to your code, or even add this a function and call it directly.