How to change DateUtils.getRelativeTimeSpanString strings? - android

I'm trying to convert a date to relative date.
For example
12-03-2017 --> 2 years ago.
I'm using an android class which is "DateUtils.getRelativeTimeSpanString"
This class works just fine. But I have a little problem.
My app will serve in Turkish language. But method returns some very old sentence.
When relative time is equal to "2 days ago" class must return "2 gün önce" which is literal translation of "2 days ago". But instead it returns "Evvelsi gün" Which has same meaning but old sentence and I don't want to use that
How to change this string for Turkish language.
I did this:
if(DateUtils.getRelativeTimeSpanString(list.get(position).getCreatedAt().getTime(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS).toString().toLowerCase().equals("evvelsi gün")){
//if class retuned unwanted word then dont use it but use preferred word.
holder.postdate.setText("2 gün önce");
}
else{
//if class returned preferred word use it
holder.postdate.setText(DateUtils.getRelativeTimeSpanString(list.get(position).getCreatedAt().getTime(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS));
}
But as you can see I'm setting textView's text with hardcoded strings. Is this a good solution? Is there any more professional ways?

Related

RTL issue in string containing English, Hebrew and digits in Android (Java)

I have an issue when mixing in one string English, Hebrew and digits.
The order of digits next to Hebrew is getting reversed, no matter what order I make - fist digit and then text, of first text and then Hebrew - it's getting reversed to: on the left digit, on the right text.
My text example is:
String leftPart = "10 gr";
int numder = 8;
String hebrewText = "כפות";
String rightPart = hebrewText + " " + number;
String finalString = leftPart + " · " + rightPart; //10 gr · כפות 8
I want to display the digit 8 in the end of this string, after the Hebrew word, not before it, but I'm unable to do it even here...it's getting reversed because of the English text in the begging.
Even if I change the order to:
String rightPart = number + " " + hebrewText ;
the result is the same...
Any ideas? It's looks like something simple that I'm missing
A tip for forcing English to be shown nicely when mixed with Hebrew:
Wrap the English (or numbers) words with LRI and PDI (check here: https://unicode.org/reports/tr9/ ) .
For example, instead of these (first word is in English) :
<string name="test">ABC היא האפליקציה הכי טובה</string>
<string name="test2">%1$s היא האפליקציה הכי טובה</string>
Use these:
<string name="test">\u2066ABC\u2069 היא האפליקציה הכי טובה</string>
<string name="test2">\u2066%1$s\u2069 היא האפליקציה הכי טובה</string>
Other useful ones can be found here:
https://stackoverflow.com/a/10989502/878126
Nothing is screwing up here, this is actually correct behavior. The number is coming after the end of the hebrew word- the end of the hebrew word is on the left. What you seem to want is for the number to come before the hebrew word. But when you combine it with english like that it doesn't know tht the number is supposed to be bound to the hebrew part and not the english part, so putting it before the hebrew doesn't work either.
I'd suggest putting the number before the hebrew part and wrapping the number and hebrew text in unicode right to left mark characters, to tell it explicitly the 8 is part of the right to left text.
Alternatively you could put the number after the hebrew text but use an rtl mark before the hebrew and a ltr mark after. Which is probably a slightly better way of doing things overall if you want more complex embedding elsewhere.

How to describe duration in Android?

I'm writing small app and I need to write duration of sport event in i18n. Im using PrettyTime library for date, but when I attempt to use DateUtils or PrettyTime, I have issues..
For example I want to say that duration is 2 minutes. I need some way to pass it to library which supports i18n and accept milliseconds and return Chars.
In android we have:
com.android.internal.R.plurals.duration_minutes
But I can't access to it from my App. Is there any way to make it using correct way and not writing own plurals for all languages?
Thank you
I am not sure which issues you are talking about in context of Android-DateUtils and PrettyTime-library. But I know for sure that Android-DateUtils does not perfectly manage the plural rules of various languages (especially not slavish languages or arabic because it only knows singular and one plural form which is too simple). See for example this Android-issue. About the PrettyTime-library, the same objection is valid if you consider Arabic - see the source.
My recommendation:
Try out my library Time4A (a new AAR-library). Then you can use this code to process a millisecond-input and to produce a localized minute-string:
// input
long millis = 1770123;
// create a duration
Duration<ClockUnit> duration = Duration.of(millis, ClockUnit.MILLIS);
// normalization to (rounded) minutes
duration = duration.with(ClockUnit.MINUTES.rounded());
String s = PrettyTime.of(Locale.ENGLISH).print(duration, TextWidth.WIDE);
System.out.println(s); // 30 minutes
Example for Korean (answer to comment of #Gabe Sechan):
String s = PrettyTime.of(new Locale("ko")).print(duration, TextWidth.WIDE);
System.out.println(s); // 30분 (korean translation of "30 minutes")
Example for Arabic (right to left):
String s = PrettyTime.of(new Locale("ar")).print(duration, TextWidth.WIDE);
System.out.println(s); // ٣٠ دقيقة
This solution currently supports ~90 languages (more than in PrettyTime-library) and three text widths (full, abbreviated or narrow). Accurate pluralization handling is automatically included. Time4A uses its own language resources based on CLDR-data (independent from Android). But you are free to override those resources by defining your own assets (in UTF-8).
About normalization: I just showed the variant which you have described in your question. However, there are many more ways how to normalize durations in Time4A(J). This page will give you more ideas how to use that feature.
If you still miss some languages then just tell me, and I will support it in the next versions of Time4A. Currently supported languages can be found in the tutorial.

Search through a string and return specific text android [duplicate]

This question already has answers here:
How do I split a string in Java?
(39 answers)
Closed 8 years ago.
Hi how can i return Grapes from the string below, i want to search through a string and return a text in the middle of the string after four character and discard the rest of the text.
String grapes = "2 x Grapes #Walmart";
Thanks for helping me guys the code below worked
String grapes = "2 x Grapes #Walmart";
String[] split = grapes.split("\\s+");
String fsplit = split[2];
my suggestion will be not to use a regex for this . But just in case you find no other way round, use this :
(\w+\s){3}
you will get the third word in the first backreference. \1 or $1 whichever supports your compiler
demo here : http://regex101.com/r/jB5nN0
This may help you:
^[\\d]+\\sx\\s(.*?)\\s+.*?$
Explanation:
Assert position at the beginning of a line (at beginning of the string or after a line break character) «^»
Match a single digit 0..9 «[\d]+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the character “x” literally «x»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s»
Match the regular expression below and capture its match into backreference number 1 «(.*?)»
Match any single character that is not a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match any single character that is not a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Assert position at the end of a line (at the end of the string or before a line break character) «$»

Plurals not working as intended in android

I am using Plural strings provided by android-sdk. I have used following code to create a plural string:
<plurals name="valuestr">
<item quantity="zero">Choose a value.</item>
<item quantity="one">%d unit.</item>
<item quantity="other">%d units.</item>
</plurals>
Java Code:
textView.setText(getResources().getQuantityString(R.plurals.valuestr,0,0));
When i am setting any value other than '0', this is working fine but when i am setting '0' it is showing '0 unit.'.
Please help!
Update
While searching more on the internet i came across a workaround which uses java.text.MessageFormat class:
<resources>
<string name="item_shop">{0,choice,0#No items|1#One item|1<{0} items}</string>
</resources>
Then, from the code all you have to do is the following:
String fmt = resources.getText(R.string.item_shop);
textView.setText(MessageFormat.format(fmt, amount));
You can read more about the format strings in the javadocs for MessageFormat
A post was recently made on G+ about this.
In short, it is because this will not pick the closest match by Integer ( 0 = zero), but because it will look for the best grammatical pick.
In your example, you use units.
The correct usage would be;
0 units
1 unit
2 units
Making, zero equal to pretty much any other quantity above 1
Read the full story here;
https://plus.google.com/116539451797396019960/posts/VYcxa1jUGNo
Plurals defined in <plurals> sections of resource files are only to be used for a grammatical distinction with respect to singular/plural strings. You should not use them for other display logic, as you did. You should add some checking logic in your code instead.
The Android developer's guide clearly states this:
Although historically called "quantity strings" (and still called that
in API), quantity strings should only be used for plurals. It would be
a mistake to use quantity strings to implement something like Gmail's
"Inbox" versus "Inbox (12)" when there are unread messages, for
example. It might seem convenient to use quantity strings instead of
an if statement, but it's important to note that some languages (such
as Chinese) don't make these grammatical distinctions at all, so
you'll always get the other string.
Your workaround - although working technically for your current implementation - does not appear like a clean solution either, in my opinion. Future business requirements may make it necessary to include more sophisticated logic than just displaying a different text. Or you may have a generic "no items selected" string in your resource file used at different locations, which could be reused only if you did not stick to your solution.
Generally, I would avoid using two different formatting techniques (String.format style formatter %d vs. MessageFormat style formatter {0} and pick one that you'd stick to in your whole application.

How to return 1 decimal place for the answer of this calculated Label in Adobe Flash Builder

I am writing code in Adobe Flash Builder for an Android application. I have written my code to do some math and return the answer to a label field. I would like to know how do I return this answer to show only 1 spot after the decimal. Here is the code
lblAnswer.text = String(Number ((sldrABSL.value) + 46.7)/28.7);
If there are any suggestions please let me know.
If I understand this correctly, you have a string representing a number, which you want to be presented with only one decimal.
Fist of all, you'd have to convert the numeric value of the string to a double:
String stringOfNumber = "100.1233123";
Double number = Double.valueOf(stringOfNumber);
Secondly, you'd have to establish the format of which to represent the double (number of decimals):
DecimalFormat oneDigit = new DecimalFormat("#,##0.0");
Set the digit to a (i.e) TextView:
myTextView.setText("" + oneDigit.format(number));
I think this should work. Is this kind of what you were asking?
Edit: Not super certain as to how to set it to a textview, but in java, printing it to screen works like this:
System.out.println(oneDigit.format(number));
Edit2: Oh, and you'll need to this import:
import java.text.DecimalFormat;
Edit3:
TextView.setText("" + oneDigit.format(number));
works fine for me.
The decimal places uses the tofixed property. It must be added at the end of the specified number that needs to contain the decimal place.
'lblAnswer.text = String(Number ((sldrABSL.value) + 46.7)/28.7).toFixed(1);
The one specifies the number of decimal places that are used.

Categories

Resources