I want to make sure the date time stored in database table is not more than 2 minutes than previous captured date time.
the result returned from Database table is in this format.
[[col1:2020-05-28 04:02:21.34]]
my codes
import java.text.SimpleDateFormat
//capture current date time
def date = new Date()
println date.format('yyyy-MM-dd hh:mm:ss.SS',TimeZone.getTimeZone('UTC'))
//wait 2 minutes then capture DB table date time
WebUI.delay(120)
PostgresdbQuery = /SELECT col1 FROM table1.test/
List resultsafter = CustomKeywords.'test.database.getPostgresSQLResults'(GlobalVariable.testPostgresdbConnString , GlobalVariable.testPostgresdbUsername , GlobalVariable.testPostgresdbPassword ,GlobalVariable.testPostgresdbDriver ,PostgresdbQuery )
println(resultsafter)
//assert
assert resultsafter < date, 'Execute time is within 2 minutes'
error
Reason:
groovy.lang.GroovyRuntimeException: Cannot compare java.util.ArrayList with value '[{col1=2020-05-28 04:02:21.34}]' and java.util.Date with value '5/28/20 1:49 PM'
The result is a list of maps. To make that check work, you would have to write it as:
assert resultsAfter.first().col1 < date
This will only work for the very first result and only if there is one. Assuming, you want to assert that for all elements, you can use every or loop the results and do the asserts for each row.
Yet, at this point i'd just let the DB do the work: select all items, that dont't match the criteria and make sure, no results are found.
Related
I'm having a bit of difficulty figuring out how to approach this function.
I have an SQLite database that is being handled by room, and I need to update entries in sharedpreferences based on this data. There is already a dao query setup to give entries by descending order of datetime:
#Query("SELECT * FROM data_table ORDER BY datetime DESC")
LiveData<List<Data>> getAllData();
These datetimes have corresponding float entries that I have to perform cumulative calculations on based on the difference of time to the next data entry's datetime. So, for example:
id datetime float
1 dt(1) 12.0f
2 dt(2) 15.0f
2 dt(3) 13.0f
I would start with
var timeDiff = ((Duration.between(LocalDateTime.parse(dt(1)),LocalDateTime.parse(dt(2)).toMillis())/1000).toFloat()
var currentValue = [big complicated formula applied to 12.0f based on timeDiff]
and then I would move on to
currentValue = (currentValue + 15.0f)
timeDiff = ((Duration.between(LocalDateTime.parse(dt(2)),LocalDateTime.parse(dt(3)).toMillis())/1000).toFloat()
currentValue = [big complicated formula applied to previous currentValue based on timeDiff]
until I get to the last entry, where I store that datetime and currentValue as a sharedpreference.
I'm not really sure how to go about this though. I was thinking of using a mutable array list:
mDataViewModel = ViewModelProvider(this).get(DataViewModel::class.java)
var tarray: MutableList<List<Data?>?> = ArrayList()
mDataViewModel.getAllData().observe(this, Observer<List<Data>>() {
fun onChanged(data: List<Data?>?) {
tarray.add(data)
}
})
Toast.makeText(this#MainActivity, tarray.toString(), Toast.LENGTH_SHORT).show()
and then performing the calculations on the list sequentially, but it doesn't appear to be populating. I would much prefer to perform the cumulative calculations as they're fed from the database. This is my first time using SQlite though, and I'm not there is a much easier way of accomplishing this than what I'm attempting to do. Any advice would be greatly appreciated.
I would much prefer to perform the cumulative calculations as they're fed from the database. This is my first time using SQlite though, and I'm not there is a much easier way of accomplishing this than what I'm attempting to do. Any advice would be greatly appreciated.
Perhaps consider the following as a pointer which may be along the lines of what you are trying to accomplish. That is getting the data you want from the database.
/* Create the TEST ENVIRONMENT */
DROP TABLE IF EXISTS data_table;
CREATE TABLE IF NOT EXISTS data_table (id INTEGER PRIMARY KEY, datetime TEXT, float REAL);
INSERT INTO data_table (datetime,float) VALUES('2021-04-01 12:00',12.0),('2021-04-01 13:00',15.0),('2021-04-01 16:00',13.0);
/* Show the raw/actual data */
SELECT * FROM data_table;
/* now extract the useful data */
WITH y AS (
SELECT
datetime,
float,
/* Get the float value of the previous row (as first would be NULL use COALESCE get the current float value )*/
COALESCE(
(SELECT float FROM data_table WHERE datetime < x.datetime ORDER BY datetime DESC LIMIT 1 ),x.float
) AS prev_float,
COALESCE(
(SELECT datetime FROM data_table WHERE datetime < x.datetime ORDER BY datetime DESC LIMIT 1 ),
(SELECT datetime FROM data_table ORDER BY datetime ASC LIMIT 1)
) AS prev_datetime
FROM data_table AS x
)
SELECT datetime, prev_datetime, strftime('%s',datetime) - strftime('%s',prev_datetime) AS datediff_in_seconds, float, float-prev_float as floatdiff FROM y ORDER BY datetime ASC;
DROP TABLE IF EXISTS data_table; /* clean-up the testing environment */
So you start off with the following data as an example :-
And it produces :-
i.e. the manipulated data
Note the use of COALESCE to return previous values for the first row. COALESCE returns the first non-null value of the listed values. The first being the value from the previous row, which would be null for the first row so it gets the current value
in the case of the date time, datetime could have been used however as cab be seen a sub query has been used just to demonstrate the flexibility of SQlite SQL.
It's then just a matter of two additional steps for Room :-
Create the Dao query using the complex query (from the WITH .... to the SELECT .... FROM y ORDER BY datetime ASC; )
Create a suitable POJO class/data class. For the example/pointer given you'd have var's or val's for
datetime
prev_datetime
datediff
float
prev_float
floatdiff
as these are the columns returned.
This isn't really about the database or the LiveData, right? You just want a way to run through this set of data?
You could use zipWithNext to turn the data into a list of Pairs, and run a fold on that. You gave an example of how you'd handle the first case, and how you'd handle every case after that, but really they're all
currentValue = currentValue + data1's float
timeDiff = time difference between data1 and data 2
currentValue = something based on currentValue and timeDiff
where currentValue starts off as 0, so on your first run it's currentValue = 0f + 12.0f
Here's how you can do that with a fold:
// Just a basic version of the data you're working with, as a demo
data class Thing(val time: DateTime, val number: Float)
typealias DateTime = Int
val stuff = listOf(Thing(10, 12.0f), Thing(12, 15.0f), Thing(15, 17.0f))
fun main() {
stuff.zipWithNext().fold(0f) { currentValue, (data1, data2) ->
val timeDiff = data2.time - data1.time
val newValue = complicatedTask(currentValue + data1.number, timeDiff)
newValue
}
.run(::println)
}
fun complicatedTask(number: Float, timeDiff: Int) = number * timeDiff
>> 117.0
The accumulator you're folding through is that currentValue float, so you start with 0f and return the new value at the end of the fold function, and that's what pops out at the end.
If you want the datetime too, you can make that part of the accumulator - I'm just gonna reuse that data class but you can make your own, or use a basic Pair or whatever:
stuff.zipWithNext().fold(Thing(0, 0f)) { (_, currentValue), (data1, data2) ->
val timeDiff = data2.time - data1.time
val newValue = complicatedTask(currentValue + data1.number, timeDiff)
Thing(data1.time, newValue)
}
>> Thing(time=12, number=117.0)
Using a start value with time=0 (gotta have something), and at the end of the function you're returning the first datetime, i.e. d(1) when you're comparing d(1) and d(2). You could return the other one if that's what you wanted. I just gave it an anonymous _ variable name in the function because you don't actually use it in there, you only care about it when it pops out as the result.
I'm not sure if that helps with what you're doing - if you want to keep running this process every time a new value is observed (maybe that's why you want the datetime in the result?) you could make the lambda a separate function, that way the fold can call it, but you can also use it yourself for one-off updates when you get some new data. And you can use that result as the start value for a new fold, if you need to run it on a bunch more values. Hope that makes sense!
I have difficulties with a query I have to change to limit the data I export from a Progress database. I export "myorderdate" to a text file. However, I have to limit the data to only orders after year 2012.
OUTPUT STREAM s1 TO VALUE(exportFileStringDirectory).
FOR EACH poTable NO-LOCK WHERE
ponum = 1 AND
/* this doesn't work -->*/
/*myorderdate.YEAR >= DATE("2012").YEAR AND*/
conum = 1:
PUT STREAM s1 UNFORMATTED
ISO-DATE(myorderdate)
SKIP.
END.
OUTPUT STREAM s1 CLOSE.
I'm new to Progress 4GL databases and work with databases altogether. All I have to do is a small change to the code so please forgive me if the description lacks some vital information.
I would code it like this:
FOR EACH poTable NO-LOCK WHERE
ponum = 1 AND conum = 1 and
myorderdate >= 1/1/2012:
That way you avoid having to evaluate the YEAR() function with every iteration of the loop.
Use YEAR function. YEAR() function takes input as date and returns year value of the date as an integer.
So, replace
myorderdate.YEAR >= DATE("2012").YEAR
with:
YEAR(myorderdate) >= 2012
I have an Oracle table which has a date column ( say its name is start_date) that has stored date as UTC date. I have another column that stores a timezone (like 'America/Los_Angeles'). My requirement is I need to display the date column with timestamp corresponding to the timezone stored in the timezone column.
I initially wrote a function that accepts utc_date and the timezone and returns the date as below:
return utc_date + (SUBSTR (TZ_OFFSET (timezone), 1, 1) || '1')
* TO_DSINTERVAL (
'0 '
|| SUBSTR (TZ_OFFSET (timezone), 2, 5)
|| ':00');
but I realized a flaw. It calculates offset based on current time. So it now returns -00 08:00:00.000000 for Los_Angeles. But if the date stored in the utc_date was a date when daylight was enforced, the tz_offset value is not valid anymore. Can someone provide me some pointers how can I approach this problem?
I found a solution to my problem. Instead of relying on TZ_OFFSET, I decided to do the following
return cast(from_tz(cast(utc_date as timestamp),'UTC') at time zone timezone as date);
This is returning me the desired date. If anyone see a flaw let me know
I am using MS SQL server 2008. Here I need to compare the newly entered start time and End time of an event with the existing event timings. In the Database I need to check the new Starting time and End time values and the time Period should not match with the existing/ already booked event timings.
I need to check this condition in the Database stored procedure, if the condition is satisfied then only accept the event. Best example is Conference hall booking.
SELECT #count = COUNT (EventID) FROM TblEvent WHERE (('#STARTTIME' BETWEEN StartTime AND EndTime) or ('#ENDTIME' BETWEEN StartTime AND EndTime));
IF #count = 0
Begin
Select #count = COUNT (EventID) FROM TblEvent WHERE (('#STARTTIME' < StartTime and '#ENDTIME' > EndTime));
END
IF #count > 0
BEGIN
SELECT 'Event is Already Exists at that point of time please select another Time ' AS 'MESSAGE';
END
Else
BEGIN
//ADD QUERY TO SAVE THE THE EVENT IN DB//
SELECT 'Event is Added' AS 'MESSAGE';
END
NOTE:
#STARTTIME = USER ENTERED START TIME,
#ENDTIME =USER ENTERED END TIME
You can use 24 hour format to solve this in your logic. you have to save existing event timings in Database. whenever new event timings entered, you need to compare with existing both start & end timings with previous ones.
For Example:
Event1: x1 to y1
Event2; x2 to y2
if(x2==x1 && y2==y1)
if(x2>x1 &&x2<y1) andif(y2<y1)
...so on based on your requirement.
Answer is (StartA <= EndB) and (EndA >= StartB). Please, read these: Determine Whether Two Date Ranges Overlap
Hey Sanjeev try the following code..!
Select * From your Event
WHERE ('A' BETWEEN StartTime AND EndTime) or ('B' BETWEEN StartTime AND EndTime)
Note:
Here A and B are your Start time and End Time,
and Italics are your database values.
If I had understood correctly, this should solve the problem.
Let us take A and B are your start time. X and Y are previously in Database.
Then (A,B) does not over lap (X,Y) when X > B or Y < A this can be told as the new event must finish before the previous one or it must start after the previously available one. So query must be
...
Where NewStartTime > EndTime or NewEndTime < StartTime;
Using vs2008 I have a SQL Server database attached to my web app. I want to use a computed time column in the database, along the lines of :
timenow is 1 column
hoursleft is another column
timeend would be another column.
I want timeend to = timenow + hoursleft.
Is it possible to do that, and if so what would the formula be that I would enter into the computed column field, and, what datatype would the columns be, timenow and timeend I would expect to be time(7) and hoursleft an int. But is that correct? THanks for any help.
TimeNow is datatype datetime, populated with function GetUtcDate().
HoursLeft is an int, populated as required.
TimeEnd is a computed column of type datetime, computed as DateAdd(hh, HoursLeft, TimeNow).
You'd use this to calculate timeend from the 2 existing columns hoursleft and timenow
CAST(DATEADD(hour, hoursleft, timenow) AS time(7))
DATEADD return type is
The return data type is the data type of the date argument
So the explicit CAST probably isn't needed if timenow is time(7) as you mentioned
DATEADD(hour, hoursleft, timenow)