Date inequality is not functioning in android - 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) {
...
}

Related

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")
}

CouchDB filtering by date

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 }
]
}

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
}

short month names

I'm trying to get a short month name by passing the month int to a function.
But it always returns 'Jan'
Here is the function:
public static String getMonthName_Abbr(int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, month);
SimpleDateFormat month_date = new SimpleDateFormat("MMM");
String month_name = month_date.format(month);
return month_name;
}
You simply need to pass cal.getTime() to your format call, rather than month itself.
See the working demo at http://ideone.com/kKrGY9
I am not sure why your code worked as given, seeing as how format expects a Date and not an int; however, if somehow it did, perhaps the value of month, being a small integer was interpreted as a time around the epoch (January 1, 1970). Just a thought, but at any rate, your function will work with that one small change.
public static String getMonthName_Abbr(int month) {
final String[] allMonths = DateFormatSymbols.getInstance(Locale.getDefault()).getShortMonths();
return (month >= 0 && month < allMonths.length) ? allMonths[months] : "Invalid month";
}
if you already have the month number (1-12), here's an easy way to determine whether it's a short- or long-month without regex too much hard-coding :
jot 12 | {m,g,n}awk '
function shortMonth_v1(_) { return \
(_ % 2) != (+_ < 8) }
function shortMonth_v2(_) { return \
(_ + (+_ < 8)) % 2 }'
2
4
6
9
11
function longMonth_v1(_) { return \
(_ % 2) == (+_ < 8) }
function longMonth_v2(_) { return \
(_ + (7 < +_)) % 2 }
1
3
5
7
8
10
12
...v1() and ...v2() for both groups basically identical, reshuffling things around, so which one you prefer is just a matter of taste and personal preference
assuming if you really wanna match it by string-regex of first-3 letters, June is by far the hardest on
tolower($0) ~ /[fpv]|un/
/[bpv]|un/ # these 2 work as long as the input isn't all-caps
/[bpo]|un/
/^F|p|un|v/ # assuming first letter capitalized, others lower-case
/[FNp]|un/
Fe[b] b # can't use [e] to match
# since that'll grab in D[e]cember
A[p]r p
J[u][n] un
Se[p] p
No[v] v
/[acgl]/ # my favorite, by far
J[a]n a
M[a]r a
M[a]y a
Ju[l] l
Au[g] g
O[c]t c
De[c] c
/^M|an|[cgl]/ # alternatives
/[Mc]|an|u[^n]/

How to prevent EditText from breaking a line after punctuation

As default, an Android EditText will break a line if the line is longer than the view, like this:
Thisisalineanditisveryverylongs (end of view)
othisisanotherline
or if the line contains a punctuation character, like this:
Thisisalineanditsnotsolong; (several characters from the end of view)
butthisisanotherline
As a requirement of my work, the text has to break a line only if the line is longer than the view, like this:
Thisisalineanditsnotsolong;andt (end of view)
hisisanotherline
There must be a way to achieve this, am I right? So far I haven't found anyway to do this.
The way TextView (and EditText) breaks the text is through private function calls to BoringLayout internally. So, the best way would be to sublcass EditText and rewrite these functions. But it will not be a trivial task.
So, in the TextView class there are creations of different classes for text style. The one we look is DynamicLayout. In this class we reach to a reference of the class StaticLayout (in a variable called reflowed). In the constructor of this class you will find the text wrap algorithm:
/*
* From the Unicode Line Breaking Algorithm:
* (at least approximately)
*
* .,:; are class IS: breakpoints
* except when adjacent to digits
* / is class SY: a breakpoint
* except when followed by a digit.
* - is class HY: a breakpoint
* except when followed by a digit.
*
* Ideographs are class ID: breakpoints when adjacent,
* except for NS (non-starters), which can be broken
* after but not before.
*/
if (c == ' ' || c == '\t' ||
((c == '.' || c == ',' || c == ':' || c == ';') &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
((c == '/' || c == '-') &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
(c >= FIRST_CJK && isIdeographic(c, true) &&
j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
okwidth = w;
ok = j + 1;
Here's where all the wrapping goes. So you will need to subclass take care for StaticLayout, DynamicLayout, TextView and finally EditText which - I am sure - will be a nightmare :( I am not even sure how all the flow goes. If you want - take a look at TextView first and check for getLinesCount calls - this will be the starting point.
This Line Breaking algorithm in Android really sucks, it isn't even logically correct - a comma can not be the last character of a line. it only produces unnecessary line breaks, which results in extremely weird text layout.
Hi Here is one method I first get from another guy and then make a little bit changes, it really works for me you can have a try.
//half ASCII transfer to full ASCII
public static String ToSBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i< c.length; i++) {
if (c[i] == 32) {
c[i] = (char) 12288;
continue;
}
if (c[i]<=47 && c[i]>32 )
c[i] = (char) (c[i] + 65248);
}
return new String(c);
}
}
here it is. I change some special characters from half corner to full corner, such as "," ".", and the effect is pretty good. You can have try.

Categories

Resources