get today data from room database - kotlin

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

Related

Interval Date to days [duplicate]

I have two timestamp columns: arrTime and depTime.
I need to find the number of munites the bus is late.
I tried the following:
SELECT RouteDate, round((arrTime-depTime)*1440,2) time_difference
FROM ...
I get the following error: inconsistent datatype . expected number but got interval day to second
How can i parse the nuber of minutes?
If i simply subtract: SELECT RouteDate, arrTime-depTime)*1440 time_difference
The result is correct but not well formatted:
time_difference
+00000000 00:01:00 0000000
The result of timestamp arithmetic is an INTERVAL datatype. You have an INTERVAL DAY TO SECOND there...
If you want the number of minutes one way would be to use EXTRACT(), for instance:
select extract( minute from interval_difference )
+ extract( hour from interval_difference ) * 60
+ extract( day from interval_difference ) * 60 * 24
from ( select systimestamp - (systimestamp - 1) as interval_difference
from dual )
Alternatively you can use a trick with dates:
select sysdate + (interval_difference * 1440) - sysdate
from (select systimestamp - (systimestamp - 1) as interval_difference
from dual )
The "trick" version works because of the operator order of precedence and the differences between date and timestamp arithmetic.
Initially the operation looks like this:
date + ( interval * number ) - date
As mentioned in the documentation:
Oracle evaluates expressions inside parentheses before evaluating those outside.
So, the first operation performed it to multiply the interval by 1,440. An interval, i.e. a discrete period of time, multiplied by a number is another discrete period of time, see the documentation on datetime and interval arithmetic. So, the result of this operation is an interval, leaving us with:
date + interval - date
The plus operator takes precedence over the minus here. The reason for this could be that an interval minus a date is an invalid operation, but the documentation also implies that this is the case (doesn't come out and say it). So, the first operation performed is date + interval. A date plus an interval is a date. Leaving just
date - date
As per the documentation, this results in an integer representing the number of days. However, you multiplied the original interval by 1,440, so this now represented 1,440 times the amount of days it otherwise would have. You're then left with the number of seconds.
It's worth noting that:
When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error. For example, the next two statements return errors:
The "trick" method will fail, rarely but it will still fail. As ever it's best to do it properly.
SELECT (arrTime - depTime) * 1440 time_difference
FROM Schedule
WHERE ...
That will get you the time difference in minutes. Of course, you can do any rounding that you might need to to get whole minutes....
Casting to DATE first returns the difference as a number, at least with the version of Oracle I tried.
round((cast(arrTime as date) - cast(depTime as date))*1440)
You could use TO_CHAR then convert back to a number. I have never tested the performance compared to EXTRACT, but the statement works with two dates instead of an interval which fit my needs.
Seconds:
(to_char(arrTime,'J')-to_char(depTime,'J'))*86400+(to_char(arrTime,'SSSSS')-to_char(depTime,'SSSSS'))
Minutes:
round((to_char(arrTime,'J')-to_char(depTime,'J'))*1440+(to_char(arrTime,'SSSSS')-to_char(depTime,'SSSSS'))/60)
J is julian day and SSSSS is seconds in day. Together they give an absolute time in seconds.

convert local time to utc and add to utc datetime moment

I have a user input where the user enters year, month and day and I create a date object
let userDate = new Date(year, month, day)
and then from a user input where the user enters minutes and hours (into variables minutes and hours)
I need to convert this date and time into UTC timestamp, using moment and I'm not sure about it. Can I just do
let utcTimestamp = moment.utc(date.toISOString()).hour(hours).minutes(minutes);
For example: if a user enters a date of 13-Mar-2018 and time of 8:45 AM (in GMT timezone), then I could use the above line of code to get UTC timestamp as I can directly add hours and minutes to the date
if a user enters a date of 13-Aug-2018 and time 8:45 (which is GMT +1, due to daylight savings time change) then with above line I might be creating a wrong date.
... I create a date object
let userDate = new Date(year, month, day)
Be careful here, you need to subtract 1 from the month, as they are numbered 0-11 by the Date instead of the usual 1-12.
and then from a user input where the user enters minutes and hours (into variables minutes and hours)
I need to convert this date and time into UTC timestamp, using moment ...
You don't need Moment for this. Just call .toISOString() on the Date object. It implicitly converts to UTC before generating the string.
var utcString = new Date(year, month-1, day, hours, minutes).toISOString();
... Can I just do
let utcTimestamp = moment.utc(date.toISOString()).hour(hours).minutes(minutes);
No, that doesn't make sense. That would only work if the date was entered in local time but the time was entered in UTC. Such a difference in behavior would surely be confusing to your user - especially if the UTC date was different than the local date.
... if a user enters a date of 13-Aug-2018 and time 8:45 (which is GMT +1, due to daylight savings time change) then with above line I might be creating a wrong date.
The conversion from local time to UTC will automatically take into account any daylight saving adjustment that is being observed by the local time zone. You do not need to do any additional adjustment on your own.
This is a snippet i used to convert an outlook calendar event from UTC to local time. The same Technique could be used for other scenarios.
//Get the users timezone
let timeZone = item.originalStartTimeZone;
//Get the start datetime in UTC time
let timeStart = item.start.dateTime;
//Calculate the negative offset.
let offset = - timeStart.localeCompare(timeZone);
//Add the calculated offset to the UTC start time
let localStartTime = addHours(timeStart, offset);

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 DATETIME to Unix Epoch in Informix

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).

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.