Compare the Room Database and fetch the respective Data - mvvm

We have Birthdate and Phone Number as user data. We need to Compare Today's date with Birthdate and fetch the Phone number to send an SMS.
We tried to use Repo class and View Model class, but unable to fetch details.

If you store the birthdate in a format supported by SQLite
see https://www.sqlite.org/lang_datefunc.html
Then you can use the 'now' timevalue (i.e. the date/ datetime NOW (i.e. when the query is run)).
As an example consider the following based upon a table (#Entity annotated class when dealing with Room) with 2 columns dob and altdob
two different formats
dob stores the time as a Long (more efficient storage wise)
altdob stores the date as a string format YYYY-MM-DD
4 rows are inserted with varying dates (both columns storing the same date)
Then a SELECT query that extracts the age (roughly) 3 ways and outputs the ages (3 columns output).
DROP TABLE IF EXISTS example; /* just in case table still exists */
CREATE TABLE IF NOT EXISTS example (dob INTEGER, altdob TEXT); /* create the table (room will do this) */
/* Add some data */
INSERT INTO example VALUES
(strftime('%s','1957-01-08'),'1957-01-08'),
(strftime('%s','1967-02-08'),'1967-02-08'),
(strftime('%s','1977-03-08'),'1977-03-08'),
(strftime('%s','1987-04-08'),'1987-04-08')
;
SELECT * FROM example; /* result 1 - the data as it is stored in the table */
/* result 2 the age in years (approx) using some of the datetime functions based upon the run/execution date */
SELECT
(strftime('%s','now')-dob) / (365 /* days in a year (close) */ * 24 /* hours in a day*/ * 60 /* mins in hour */ * 60 /* secs in minute*/) AS age,
(strftime('%s',date('now')) - strftime('%s',date(altdob))) / (365 * 24 * 60 * 60) AS altage,
date('now') - date(altdob)
FROM example;
DROP TABLE IF EXISTS example; /* cleanup demo environment */
When executed then the results are:-
Result 1
note the first column is the number of seconds since or before (if negative) 00:00:00 on 1st Jan 1970.
The second is obvious
the dates are the same just stored in different formats (both supported by the SQLite datetime functions)
Result 2
note that really there are not 365 days in a year (due to leap years)
Doing the above in Room (not mvvm for brevity/convenience)
First the Database related components:-
#Entity
data class Example(
#PrimaryKey
val dob: Long,
val altdob: String
)
data class POJOToGet3Ages(
val age: Int,
val altage: Int,
#ColumnInfo(name = "otheraltage") /* change to expect the output column name to be otheraltage instead of actual field name */
val notTheSameAsOutputColumnName: Int
)
#Dao
interface TheDAO {
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(example: Example): Long
#Query("SELECT " +
"(strftime('%s','now')-dob) / (365 /* days in a year (close) */ * 24 /* hours in a day*/ * 60 /* mins in hour */ * 60 /* secs in minute*/) AS age," +
"(strftime('%s',date('now')) - strftime('%s',date(altdob))) / (365 * 24 * 60 * 60) AS altage," +
"date('now') - date(altdob) AS otheraltage " +
"FROM example;")
fun getAllAges(): List<POJOToGet3Ages>
}
#Database(entities = [Example::class], exportSchema = false, version = 1)
abstract class TheDatabase: RoomDatabase() {
abstract fun getTheDAO(): TheDAO
companion object {
private var instance: TheDatabase?=null
fun getInstance(context: Context): TheDatabase {
if (instance==null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
.allowMainThreadQueries() /* run on main thread for brevity/convenience */
.build()
}
return instance as TheDatabase
}
}
}
To utilise the above some activity code (MainActivity) that will replicate the demo above (add the same 4 rows) and extract the ages based upon the date now and output the results to the log :-
class MainActivity : AppCompatActivity() {
lateinit var dbInstance: TheDatabase
lateinit var dao: TheDAO
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dbInstance = TheDatabase.getInstance(this)
dao = dbInstance.getTheDAO()
dao.insert(Example(-409622400,"1957-01-08"))
dao.insert(Example(-91411200,"1967-02-08"))
dao.insert(Example(226627200,"1977-03-08"))
dao.insert(Example(544838400,"1987-04-08"))
for (ages in dao.getAllAges()) {
Log.d("DBINFO","Ages is ${ages.age} ALTAGE is ${ages.altage} OTHERALTAGE is ${ages.notTheSameAsOutputColumnName}")
}
}
}
When run the log includes:-
D/DBINFO: Ages is 66 ALTAGE is 66 OTHERALTAGE is 66
D/DBINFO: Ages is 55 ALTAGE is 55 OTHERALTAGE is 56
D/DBINFO: Ages is 45 ALTAGE is 45 OTHERALTAGE is 46
D/DBINFO: Ages is 35 ALTAGE is 35 OTHERALTAGE is 36

Related

SQFlite rawquery to get the closest datetime

I'm programming a birthday app and want to use sqflite to sort the nearest date.
Through the page: SQLite query to get the closest datetime
I found out about strftime, but unfortunately I don't know how to use it with Flutter. Here are some examples how to sort a date and how I try to find the current date with strftime.
Future<List<Map<String, dynamic>>> getSortDateMapListToDate(bool sort) async {
Database db = await this.database;
String sortingDirection = '$colDate DESC';
if(!sort) {
sortingDirection = '$colDate ASC';
}
DateTime test = DateTime.now();
//var result = await db.query(dateTable, orderBy: sortingDirection);
var result = await db.rawQuery('SELECT * from $dateTable orderBy abs(strftime("%s",$test) - strftime("%s", $colDate))');
return result;
}
Maybe there is another possibility or someone has already worked with rawquerys and strftime.
For any kind of tip or help I would be grateful.
EDIT:
With the help from #heitor murara i edit my code:
var result = await db.rawQuery(
"SELECT s.id, s.name, s.date, s.priority, (strftime('%y-%m-%d', '2020-06-30') - strftime('%y-%m-%d', s.$colDate)) as 'TestDate' "
"FROM $dateTable s "
"ORDER BY TestDate"
);
the dates i use: 30.06.2020 and with strftime('%s) i get the rows:
2015-08-15 // 32 remaining days
2010-11-03 // 126 remaining days
2010-07-10 // 10 remaining days
1994-07-17 // 17 remaining days
1993-06-29 // 364 remaining days
with strftime('%y-%m-%d) i get the rows:
1994-07-17 // 17 remaining days
1993-06-29 // 364 remaining days
2015-08-15 // 32 remaining days
2010-11-03 // 126 remaining days
2010-07-10 // 10 remaining days
what I am trying to achieve:
2010-07-10 // 10 remaining days
1994-07-17 // 17 remaining days
2015-08-15 // 32 remaining days
2010-11-03 // 126 remaining days
1993-06-29 // 364 remaining days
a other solution that is in my mind, would be a trigger, who "check" every day if the date changes, the remaining days are calculated dynamically.
Has someone a hint? :)
The strftime() function you are using do this:
The strftime() routine returns the date formatted according to the format string specified as the first argument.
So, if all your dates were in a format like this: 2020-06-28 you could run a rawQuery simply like this to make the ordering:
SELECT d FROM datetime_text ORDER BY d ASC;
However, if they are not, you can then use the strftime() function to format your date to than order:
SELECT strftime('%Y-%m-%d', d) FROM datetime_text ORDER BY d ASC;
The dates would be returned in something like this:
2020-06-27
2020-06-28
2020-06-28
2020-06-28
2020-06-29
In your example, I believe you can achieve what you want with something like this:
var result = await db.rawQuery("SELECT strftime('%Y-%m-%d', <column-name>) FROM $dateTable ORDERBY $sortingDirection");
As you can see I replaced the * from your query by a <column-name> just update it with your column name.
Ps.: Since you are working with birthdays, the format '%Y-%m-%d' will do the job, you don't need to use times also.

How do I express a date type in TypeScript?

How do I express dates in TypeScript? Dates aren't a TypeScript type, so do I use any or object? Seems like there would be a "right" way to do:
let myDate: any = new Date();
I couldn't find much on Google, despite it being such a simple question.
The type is Date:
const d: Date = new Date(); // but the type can also be inferred from "new Date()" already
It is the same as with every other object instance :)
Every class or interface can be used as a type in TypeScript.
const date = new Date();
will already know about the date type definition as Date is an internal TypeScript object referenced by the DateConstructor interface.
And for the constructor you used, it is defined as:
interface DateConstructor {
new(): Date;
...
}
To make it more explicit, you can use:
const date: Date = new Date();
You might be missing the type definitions though, the Date is coming for my example from the ES6 lib, and in my tsconfig.json I have defined:
"compilerOptions": {
"target": "ES6",
"lib": [
"es6",
"dom"
],
You might adapt these settings to target your wanted version of JavaScript.
The Date is by the way an Interface from lib.es6.d.ts:
/** Enables basic storage and retrieval of dates and times. */
interface Date {
/** Returns a string representation of a date. The format of the string depends on the locale. */
toString(): string;
/** Returns a date as a string value. */
toDateString(): string;
/** Returns a time as a string value. */
toTimeString(): string;
/** Returns a value as a string value appropriate to the host environment's current locale. */
toLocaleString(): string;
/** Returns a date as a string value appropriate to the host environment's current locale. */
toLocaleDateString(): string;
/** Returns a time as a string value appropriate to the host environment's current locale. */
toLocaleTimeString(): string;
/** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */
valueOf(): number;
/** Gets the time value in milliseconds. */
getTime(): number;
/** Gets the year, using local time. */
getFullYear(): number;
/** Gets the year using Universal Coordinated Time (UTC). */
getUTCFullYear(): number;
/** Gets the month, using local time. */
getMonth(): number;
/** Gets the month of a Date object using Universal Coordinated Time (UTC). */
getUTCMonth(): number;
/** Gets the day-of-the-month, using local time. */
getDate(): number;
/** Gets the day-of-the-month, using Universal Coordinated Time (UTC). */
getUTCDate(): number;
/** Gets the day of the week, using local time. */
getDay(): number;
/** Gets the day of the week using Universal Coordinated Time (UTC). */
getUTCDay(): number;
/** Gets the hours in a date, using local time. */
getHours(): number;
/** Gets the hours value in a Date object using Universal Coordinated Time (UTC). */
getUTCHours(): number;
/** Gets the minutes of a Date object, using local time. */
getMinutes(): number;
/** Gets the minutes of a Date object using Universal Coordinated Time (UTC). */
getUTCMinutes(): number;
/** Gets the seconds of a Date object, using local time. */
getSeconds(): number;
/** Gets the seconds of a Date object using Universal Coordinated Time (UTC). */
getUTCSeconds(): number;
/** Gets the milliseconds of a Date, using local time. */
getMilliseconds(): number;
/** Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). */
getUTCMilliseconds(): number;
/** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */
getTimezoneOffset(): number;
/**
* Sets the date and time value in the Date object.
* #param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT.
*/
setTime(time: number): number;
/**
* Sets the milliseconds value in the Date object using local time.
* #param ms A numeric value equal to the millisecond value.
*/
setMilliseconds(ms: number): number;
/**
* Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC).
* #param ms A numeric value equal to the millisecond value.
*/
setUTCMilliseconds(ms: number): number;
/**
* Sets the seconds value in the Date object using local time.
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setSeconds(sec: number, ms?: number): number;
/**
* Sets the seconds value in the Date object using Universal Coordinated Time (UTC).
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setUTCSeconds(sec: number, ms?: number): number;
/**
* Sets the minutes value in the Date object using local time.
* #param min A numeric value equal to the minutes value.
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setMinutes(min: number, sec?: number, ms?: number): number;
/**
* Sets the minutes value in the Date object using Universal Coordinated Time (UTC).
* #param min A numeric value equal to the minutes value.
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setUTCMinutes(min: number, sec?: number, ms?: number): number;
/**
* Sets the hour value in the Date object using local time.
* #param hours A numeric value equal to the hours value.
* #param min A numeric value equal to the minutes value.
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setHours(hours: number, min?: number, sec?: number, ms?: number): number;
/**
* Sets the hours value in the Date object using Universal Coordinated Time (UTC).
* #param hours A numeric value equal to the hours value.
* #param min A numeric value equal to the minutes value.
* #param sec A numeric value equal to the seconds value.
* #param ms A numeric value equal to the milliseconds value.
*/
setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number;
/**
* Sets the numeric day-of-the-month value of the Date object using local time.
* #param date A numeric value equal to the day of the month.
*/
setDate(date: number): number;
/**
* Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC).
* #param date A numeric value equal to the day of the month.
*/
setUTCDate(date: number): number;
/**
* Sets the month value in the Date object using local time.
* #param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.
* #param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used.
*/
setMonth(month: number, date?: number): number;
/**
* Sets the month value in the Date object using Universal Coordinated Time (UTC).
* #param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.
* #param date A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used.
*/
setUTCMonth(month: number, date?: number): number;
/**
* Sets the year of the Date object using local time.
* #param year A numeric value for the year.
* #param month A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified.
* #param date A numeric value equal for the day of the month.
*/
setFullYear(year: number, month?: number, date?: number): number;
/**
* Sets the year value in the Date object using Universal Coordinated Time (UTC).
* #param year A numeric value equal to the year.
* #param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied.
* #param date A numeric value equal to the day of the month.
*/
setUTCFullYear(year: number, month?: number, date?: number): number;
/** Returns a date converted to a string using Universal Coordinated Time (UTC). */
toUTCString(): string;
/** Returns a date as a string value in ISO format. */
toISOString(): string;
/** Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization. */
toJSON(key?: any): string;
}
Typescript recognizes the Date interface out of the box - just like you would with a number, string, or custom type. So Just use:
myDate : Date;
As others have mentioned the type is Date.
This type is usefull when you want to enforce at compile time that you really have a Date object. Below is a mistake that is often make (forgetting the new keyword) and we can see that it is caught at compile time.
const date: Date = new Date();
function logDayNumber(date: Date){
console.log(date.getDay())
}
// Works fine
logDayNumber(date);
// Compile time error which happens when you forget new a String we be produced from Date()
// Argument of type 'string' is not assignable to parameter of type 'Date'
logDayNumber(Date());

How to get records with time close to Minutes = 59 And Second "close" to 59 from BD using EF

Imagine the service that writes temperature samples from sensor into DB each 10 seconds. Now I need to display these temperature values in 24-hrs report displaying only values closest to 59th minute and 59th second, neglecting the rest records stored in DB.
I started with
var query = x.Discretes.AsQueryable();
query = query.Where(dcrts => dcrts.CreationTimestamp >= startTime && dcrts.CreationTimestamp <= endTime);
query = query.Where(hrsDiscretes => hrsDiscretes.CreationTimestamp.Minute == 59);
But don't know how to make EF select the single record with max Second value for each of these Hour's records in the query...

Merge a Date object which has 04:00 as its time with another time string ("8:30am") into a new Date object

I have a mongo db with a document that has a date and a time separately.
Date object was intended to be just a date, so it has the time as
04:00 (time-zone adjusted to -4)
db.logs.findOne().date
ISODate("2014-08-05T04:00:00Z")
And there's a separate time field which is still a string
db.logs.findOne().time
8:30am
How do I merge them both into one field?
Do the combination client-side, using appropriate libraries to handle calendar and clock calculations, and then update/insert the document. MongoDB (as of 2.6, anyway) doesn't have facilities for updating to the combination server side.
db.logs.find().forEach(function(log) {
log.date = new Date(log.date.getFullYear(),
/* date */ log.date.getMonth(),
log.date.getDate(),
/* time */ parseInt(log.time)
/* + 12 if PM */ + (((log.time.charAt(log.time.length - 2) + log.time.charAt(log.time.length - 1)) === 'pm') ? 12 : 0));
db.logs.save(log);
})

SAS Return data from the last available 5 days

I have a list of intra-day prices at 9am, 10am, 11am etc. for each day (which are in number formats such as 15011 15012 etc.)
I want to only keep the observations from the last available 5 days and the next 5 available days from the date 't' and delete everything else.
Is there a way to do this?
I tried using
if date < &t - 5 or date > &t + 5 then delete;
However, since there are weekends/holidays I don't get all the observations I want.
Thanks a lot in advance!
Not much info to go on, but here is a possible solution:
/* Invent some data */
data have;
do date=15001 to 15020;
do time='09:00't,'10:00't,'11:00't;
price = ranuni(0) * 10;
output;
end;
end;
run;
/* Your macro variable identifying the target "date" */
%let t=15011;
/* Subset for current and following datae*/
proc sort data=have out=temp(where=(date >= &t));
by date;
run;
/* Process to keep only current and following five days */
data current_and_next5;
set temp;
by date;
if first.date then keep_days + 1; /* Set counter for each day */
if keep_days <= 6; /* Days to keep (target and next five) */
drop keep_days; /* Drop this utility variable */
run;
/* Subset for previous and sort by date descending */
proc sort data=have out=temp(where=(date < &t));
by descending date;
run;
/* Process to keep only five previous days */
data prev5;
set temp;
by descending date;
if first.date then keep_days + 1; /* Set counter for each day */
if keep_days <= 5; /* Number of days to keep */
drop keep_days; /* Drop this utility variable */
run;
/* Concatenate together and re-sort by date */
data want;
set current_and_next5
prev5;
run;
proc sort data=want;
by date;
run;
Of course, this solution suggests that your starting data contains observations for all valid "trading days" and returns everything without doing date arithmetic. A much better solution would require that you create a "trading calendar" dataset with all valid dates. You can easily deal with weekends, but holidays and other "non-trading days" are very site specific; hence using a calendar is almost always preferred.
UPDATE: Joe's comment made me re-read the question more carefully. This should return a total of eleven (11) days of data; five days prior, five days following, and the target date. But still, a better solution would use a calendar reference table.
Try this
/* Get distinct dates before and after &T */
proc freq data=mydata noprint ;
table Date /out=before (where=(Date < &T)) ;
table Date /out=after (where=(Date > &T)) ;
run ;
/* Take 5 days before and after */
proc sql outobs=5 ;
create table before2 as
select Date
from before
order by Date descending ;
create table after2 as
select Date
from after
order by Date ;
quit ;
/* Subset to 5 available days before & after */
proc sql ;
create table final as
select *
from mydata
where Date >= (select min(date) from before2)
and Date <= (select max(date) from after2)
order by Date ;
quit ;