CouchDB filtering by date - android

On Android using CouchDB with CouchBase Lite I am trying to replicate a database also I use filter in order to get documents with a field whose name is device_number
So I have this filter:
"1": "function(doc, req) {
if(doc.ismaster || doc._deleted)
return false;
if( 1 == doc.device_num || 22 == doc.device_num || 25 == doc.device_num || 41 == doc.device_num )
return true;
else
return false;}",
It works perfectly and I get all the documents for the devices: 1, 2 , 25 ,41.
Well now I want to get documents for device_num = 22 and 21 and whose creation_date has less than 60 days from the present day so I do:
"1": "function(doc, req) {
if(doc.ismaster || doc._deleted)
return false;
if( 22 == doc.device_num && 21 == doc.device_num && (Math.ceil((new Date(Date.now()).getTime() - new Date(doc.creation_date.split('/')[2], doc.creation_date.split('/')[1] - 1, doc.creation_date.split('/')[0]).getTime()) / (1000 * 3600 * 24)) <= 60) )
return true;
else
return false;}",
but I am not getting results, 0 documents, and is not true because in the database there are documents with less than 60 days.
what I am doing wrong?

I want to get documents for device_num = 22 and 21 and whose
creation_date has less than 60 days from the present day
English wording: "I want documents for 21 and 22" is actually "I'll accept any document where the document is for either 21 or 22":
if( (22 == doc.device_num || 21 == doc.device_num) && ...)
as no document with a single device_num can simultaneously be for devices 21 and 22.
Dates are a bit of a mess around the world and who knows if your user's are in the same time zone? Couchdb provides some examples of considering collation factors in dates, and here is an example of using number type for safe collation:
// creation:
{tstamp:+new Date(), device_num:22, ...}
// test
validstamp = +new Date() - 1000*60*60*24*60;
if( (22 == doc.device_num || 21 == doc.device_num) && Number(doc.tstamp) > validstamp)
...
Its nice to use Number() in case something went wrong in storage and you have stored a string. But as numbers, they are logically sequential without oddities of non-zero padded strings around the early 1980s and the distant future and you can later refactor to using mango indexes with:
{
"tstamp": {'$gt':validstamp},
"$or": [
{ "device_num": 21 },
{ "device_num": 22 }
]
}

Related

How to print specific numbers from a for loop using Kotlin

So I am fairly new to Kotlin and I need to generate specific numbers from a for loop of 1 to 13.
For the first output I need only odd numbers
For the second output I need numbers 2, 5, 8, 11, 14, 19 and 20 from a for loop of 0 to 20
For starters I can print an entire list using:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
for (i in 1..13){
println(i)
}
}
}
But that's it. What do I need to print the other required outputs?
Once you know how to write a for loop that prints every number, the question becomes how to identify a number that you "should" print from a number that you should not.
Your first sequence is all odd numbers, so #DipankarBaghel's answer covers that. Your second sequence seems to be all numbers for which the remainder when dividing by 3 is 2. (Except 19; did you mean 17 for that one?)
You can use the same operator in this case, but instead of checking for 0 (or for != 0) you can check that the remainder is 2:
for (i in 0..20) {
if (i % 3 == 2) {
println(i)
}
}
The key concept here is that of %, the remainder operator (sometimes called the modulo operator). The result of x % y will be the remainder when x is divided by y. Odd numbers have a remainder of 1 when divided by 2, so i % 2 == 1 will be true only for (positive) odd numbers.
To check even you need to do i%2==0 and for odd just check i%2!=0.
for (i in 1..13){
if(i%2!=0){
println("odd number "+i);
}
if(i%2==0){
println("even number "+i);
}
}
Hope this will help you.
To generate Odd numbers:
for (i in 1..13) {
if(i % 2 == 1 ){
println(i + ", ");
}
}
To Generate 2, 5, 8, 11, 14, 19 and 20:
for (i in 0..20) {
if (i % 3 == 2) {
println(i + ", ");
}
}

Is it possible to "disable" the period key in a HTML number field using an Android soft keyboard on an Android Web View html5 app?

When I check the keyCodes on the softKeyboard for .- , the e.key in JavaScript is "Unidentified" and the e.keyCode is 229 for all of those characters.
The device I am using is a TC52k scanner and the scan trigger has the same key and keyCode... so it can't be completely disabled.
I don't know how many things I tried that didn't work... but I will post some...
This is a dynamic field bound with rivets.js using JSON objects
$(document).on("keydown", ".qty-input", function(e) {
let code = e.keyCode;
if (code == 229 && $(this).val().charAt(str.length - 1) == ".") {
$(this).val($(this).val().slice(0, -1));
}
});
^Basically, that says that if the last character has the code 229 and the last character of the entered string is a '.', then cut the last character off... but doesn't work correctly.
I also did this that basically says to only accept keys that have keycodes between 48 and 57 which are keys 1-9 on the android soft keyboard.
<input class="qty-input" placeholder="0" type="number" min="0" step="1" onkeypress="return event.charCode >= 48 && event.charCode <= 57 && event.keyCode != 229" pattern="[0-9]*" autofocus>
Also didn't work...
Does anyone have experience with this and can help?
I know there's lots of unsolved posts about this online.
It's the last thing I have to do and its keeping my app from being deployed!
Also... I've tried these function using events: keyup, keydown, change, input and keypress...
Here is the best workaround that I found (since 229 also triggers the 'scanner' trigger, I have to detect whether a string includes a barcode and a quantity and will have to separate the two(the keyCode for a [.] again is the same as the keyCode for the scanner trigger))
The 2 conditions determine 2 things:
If the value is longer than 3, then it is not allowed as a quantity because the quantity can not be over '500', so when it has a length longer than 5, it is considered to be a barcode.
let oldVal = '';
let newVal = '';
let barcode = '';
$(document).on("keydown", "input.received-qty", function(e) {
let code = e.keyCode || e.which || e.charCode;
oldVal = $(this).val();
});
$(document).on("keyup", "input.received-qty", function(e) {
let code = e.keyCode || e.which || e.charCode;
newVal = $(this).val();
if (code == 229 && e.target.value.length >= 3) {
barcode = $(this).val().slice(oldVal.length - 1, -1);
$(this).val(oldVal);
} else if (code == 229 && e.target.value.length <= 3) {
let x = oldVal.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "");
$(this).val('');
$(this).val(x);
}
console.log("oldVal : ", "[", oldVal, "]", "newVal : ", "[", $(this).val(), "]");
});
This is the best way I've tried so far.

Can we check "AND" condition inside when(x)

In Kotlin refenrence, it is written as multiple conditions can be matched using comma (,) inside a when control flow. For example-
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
Here, in the first condition comma works like an OR operator.
Is there any way to write an expression to match AND condition inside when?
Yes. Although the syntax is somewhat different:
when {
x % 5 == 0 && x % 3 == 0 -> println("foobar")
x % 5 == 0 -> println("bar")
x % 3 == 0 -> println("foo")
}

Date inequality is not functioning in android

I want to display a text when time is between 20:45 and 23:15
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
if ((today.hour>=20 && today.minute>=45)
&& (today.hour<=23 && today.minute<=15) ){
MainTextView.setText("my text");}
The problem is that in this way the minutes interfere with each other (in fact it is impossible for it to be less than 15 and at the same time bigger than 45), so no text is displayed. Any ideas?
Yes, you just need to fix your logic. You only need to compare the minutes if the hour is a borderline hour. For example:
if ((today.hour > 20 || (today.hour == 20 && today.minute >= 45)) &&
(today.hour < 23 || (today.hour == 23 && today.minute <= 15)) {
...
}
Alternatively, convert the time into a "minutes of day" and do the arithmetic based on that:
int minuteOfDay = today.hour * 60 + today.minute;
if (minuteOfDay >= 20 * 60 + 45 &&
minuteOfDay <= 23 * 60 + 15) {
...
}

Time inequality between days not working

I need to set a text on a text view based on time.
If the inequality is within the day (from 5:00 to 7:30) I use:
if (today.month == 7 &&
today.monthDay == 7 &&
(today.hour > 5 || (today.hour == 5 && today.minute >= 00)) &&
(today.hour < 7 || (today.hour == 7 && today.minute <= 30)))
{DubAcademy.setText("A");}
The problem is that this code is not working for hours that go from one day to the next (i.e. 23:00 to 1:00 of the day after). I have tried this, but is not working
if (today.month == 7 &&
today.monthDay == 6 &&
(today.hour > 23 || (today.hour == 23 && today.minute >= 00)) &&
(today.monthDay <= 7 || (today.monthDay == 7 && today.hour <= 01 && today.minute <= 00 )))
{DubAcademy.setText("B");}
I know that it is because the month day is set to be 6, therefore, when date changes, the equation is no longer valid and no text is displayed.
Any ideas?
Try
if(today.month == 7
&& ((today.monthDay == 6 && today.hour >= 23)
|| (today.monthDay == 7 && (today.hour < 1 || (today.hour == 1 && today.minute == 00)))
Today.minute should always be >= 00 so it seems silly to check that.
My idea is to use 2 Time objects as the boundary for cleaner code. Set the first time to the time you want (for range that finishes until the next day, proper modification is needed). Then set the second time relative to the first one for simplified manipulation. Lastly, call normalize() to ensure its values are correct. Then you can just use after() and before() to check if the time is in range or not.
Time today = new Time();
today.setToNow();
Time t1 = new Time(today);
if(today.hour < 1){
t1.monthDay--; // set date to yesterday
}
t1.hour = 23;
t1.minute = 0;
t1.second = 0;
Time t2 = new Time(t1);
t2.hour += 2;
t2.normalize(true);
// Android will ensure the value in each field are in range
if(today.after(t1) && today.before(t2)){
// do something here
}

Categories

Resources