short month names - android

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

Related

How do I get certain row in ROOM Database by month and year

I have a table where I put Date as long and when I convert it back to String it would be "dd/mm/yyyy". I want to fetch certain data with month and year, so the custom query would be like :
SELECT id FROM things
WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009;
the example table has data like this :
id happend_at
-- ----------------
1 2009-01-01 12:08
2 2009-02-01 12:00
3 2009-01-12 09:40
4 2009-01-29 17:55
I'd like to know how to fetch data like that where the happened_at is in long and not String like the example above.
I'm currently learning to make android app using java and room database, so I made a converter to convert Date into long. The converter is like this :
import androidx.room.TypeConverter;
import java.util.Date;
public class DateConverter {
#TypeConverter
public static Date fromTimestamp(Long value)
{ return value == null ? null :
new Date(value);
}
#TypeConverter
public static Long dateToTimestamp(Date date)
{
return date == null ? null :
date.getTime();
}
}
Try using :-
SELECT id FROM things WHERE CAST(strftime('%m',happened_at / 1000,'unixepoch') AS INTEGER) = 1 AND CAST(strftime('%Y',happened_at / 1000,'unixepoch') as INTEGER) = 2009;
This works because:-
the value will be stored as a value that includes the milliseconds according to the TypeConverter as per
The getTime() method of Java Date class returns the number of milliseconds since January 1, 1970, 00:00:00 GTM which is represented by Date object.
Dividing by 1000 strips the milliseconds which is then a Unix_Time values (seconds since 00:00:00 on 1st Jan 1970).
strftime is SQLite's date/time function and can be used for conversion/formatting dates from the recognised types (see link section 2)
The unix_epoch modifier, lets the SQLite strftime function discern between numbers being either Julian Day (without 'unixepoch' modifer) or Unix Time values (with the modifier).
'%m' retrieves the month as a string padded with preceding 0's to always be 2 characters, '%Y' for the year part.
see https://www.sqlite.org/lang_datefunc.html
The CAST expression strips preceding 0's from the result should they exist i.e. converts 01 to 1.
an alternative to using CAST could be to force an integer (rather than string) value, say by adding 0 e.g. SELECT id FROM things WHERE 0 + strftime('%m',happened_at / 1000,'unixepoch') = 1 AND 0 + strftime('%Y',happened_at / 1000,'unixepoch') = 2009;

Converting string with time to minutes

I am working on an Android app that gets a time (duration) value as string.
For example, the app can get a value like: 6 hours 43 mins
or a value like: 15 mins
I am looking for a way to convert this strings to an integer value in minutes.
I have tried using this function, but I can´t extract the needed values:
str = str.replaceAll("[^\\d.]", "");
Edit:
it could be possible a result like 6 hours, the only known condition is that minutes are always rounded to an integer, the minimum value is 1 min
Using a Regex to get each couple numeric/time_unit. You can easily parse that with :
(\\d+) (\\w+)
Group 1 : numeric value
Group 2 : time unit
(note that I used a space between the two (could be optional if you want)
Using Java Pattern class to use that regex
Pattern p = Pattern.compile("(\\d+) (\\w+)");
Then you just have to iterate on each match to get the couple type/value
Matcher m = p.matcher(s);
while(m.find()){
String type = m.group(2);
int value = Integer.parseInt(m.group(1))
...
}
From that, just use a switch to convert the number into minute and add it to the variable, omitting the break to have a nice (but not efficient) converter :
switch(type){
//Add more time unit in the correct order if needed
case "days":
value *= 24;
case "hours":
value *= 60;
case "mins":
mins += value;
break;
}
Each type will convert the value into a correct number of minute, at the end, you will have the result in minutes.
Problem: There are few concerns as you never know without putting extra conditions like:
15 hours and 15 mins both will be stored in same integer value , you eventually need to differentiate them on some conditions to cater all the issues.
Coming to the question, you may achieve all this by using String split cases but you need to manually cater all the cases keeping in mind a user can use any spell words like hours can be hrs and so on
You could split the String at the whitespace and use the values in the array.
String value1 = "6 hours 43 mins";
String value2 = "15 mins";
String[] resultList1 = value1.split(" ");
String[] resultList2 = value2.split(" ");
int minutes1 = 0;
int minutes2 = 0;
if(resultList1.length == 4) {
minutes1 = Integer.parseInt(resultList1[0]) * 60 + Integer.parseInt(resultList1[2]);
} else {
minutes1 = Integer.parseInt(resultList1[0]);
}
if(resultList2.length == 4) {
minutes2 = Integer.parseInt(resultList2[0]) * 60 + Integer.parseInt(resultList2[2]);
} else {
minutes2 = Integer.parseInt(resultList2[0]);
}
System.out.println(minutes1);
System.out.println(minutes2);
The result is:
403
15
Either String split() or Pattern Matcher, as earlier answers suggest, will work. I'm not sure which will be more efficient though, but it's probably irrelevant in this case. My version:
String timeStr = "2 hours 15 mins";
String[] parts = timeStr.split(" ");
int totalMins = 0;
for(int i=1; i< parts.length; i+=2) {
// Add checking for "days", etc., if necessary.
if(parts[i].equals("hours")) {
int h = Integer.parseInt(parts[i-1]);
totalMins += 60 * h;
} else if(parts[i].equals("mins")) {
int m = Integer.parseInt(parts[i-1]);
totalMins += m;
}
}
System.out.println("totalMins = " + totalMins);
>> totalMins = 135
If you can get each minute and hours separately you can use string.replace("mins", "") then use Integer.parseInt().
If you get overral like 6 hours 43 mins you must split the string.
I am not sure whether this can be done in a single regex, but if I were you I would use a different regex to find the number of hours, the number of minutes, the number of seconds, etc.
Given a string in the format you mentioned, you can first extract the number of hours by using this regex:
\d+(?= hours?)
Then extract the number of minutes:
\d+(?= mins?)
If seconds can appear in the input string, you can use this to extract seconds as well:
\d+(?= secs?)
If any of the regexes don't match, that means there isn't that information in the string.
String time = "6 hours 43 mins";//or (43 mins) or (6 hours)
int h, m;
String[] parts = time.split(" ");
if (parts.length == 4) {
h = parts[1];
m = parts[3];
} else if (parts.length == 2) {
if (parts[1].isEqualTo("hours") {
h = parts[0];
} else if (parts[1].isEqualTo("mins") {
m = parts[0];
}
}
return h*60+m;

Entity Framework: How to calculate the range of dates from other date range

I am using an entity framework to calculate how many days from a date range with the target date range.
Let say I passed in a from date A to date B. In each row of the date I have previous log date and current log date. I want to see how many days was sitting inside between the previous log date and current log date.
My code i was currently written is:
var days = toDate.Subtract(fromDate).TotalDays;
var usageLog = (from usageLogs in context.UsageLogs
where
(usageLogs.PreviousLogDate != null
&& (DbFunctions.TruncateTime(usageLogs.CurrentServerLogDate) >= fromDate.Date && DbFunctions.TruncateTime(usageLogs.PreviousLogDate) <= toDate.Date)) ||
(usageLogs.PreviousLogDate == null
&& ((DbFunctions.TruncateTime(usageLogs.CurrentServerLogDate) >= toDate.Date) && (DbFunctions.TruncateTime(usageLogs.CurrentServerLogDate) >= fromDate.Date)))
select new
{
PackageName = usageLogs.PackageName,
estimateUsageCount = (double)usageLogs.UsageCount
});
var statistics = (from usage in usageLog
group usage
by new
{
usage.PackageName
}
into grp
select new
{
PackageName = grp.Key.PackageName,
UsageCount = grp.Sum(c => c.estimateUsageCount)
});
return statistics.ToList();
}
estimateUsageCount in the select statement is where I want to calculate the number of days sitting in between the previous and current log dates.
I am thinking to write function to do the job but don't know how to do it. I know the calculation is quite complicated. Does anyone give me an idea of how to do it.
You can do it like this:
select new
{
PackageName = usageLogs.PackageName,
estimateUsageCount = (usageLogs.CurrentServerLogs - usageLogs.PreviousServerLogs).Days
});
For the range between two dates, I found this excel formula:
=MAX(0,NETWORKDAYS(MAX(Date1, Date2),MIN(dateA,dateA)))
that it can be translated into c# like this, using the ternary operator:
0 > ((date1 > date2 ? date1 : date2) - (dateA < dateB ? dateA : dateB)).Days ? 0 : ((date1 > date2 ? date1 : date2) - (dateA < dateB ? dateA : dateB)).Days

How to find last " | " character of description

Let us suppose I have these descriptions like those below. I want fetch the description with the ending character |. How can I do this?
Description Model 1:
Whether or not Nicki Minaj deserved to receive a VMA nomination for “Anaconda” is irrelevant. The fact remains that the video broke a Vevo record for the most views in a single day, became a pop cultural phenomenon within the past year, and is now immortalized with a Minaj | wax figure at Madame Tussauds
Result model 1 should be:
Whether or not Nicki Minaj deserved to receive a VMA nomination for “Anaconda” is irrelevant. The fact remains that the video broke a Vevo record for the most views in a single day, became a pop cultural phenomenon within the past year, and is now immortalized with a Minaj |
Description Model 2:
घटनापछि बालिकाको मानसिक अवस्था ठिक नभएको र उपचार भइरहेको उनले बताइन् । महिला तथा बालबालिका टोल सुधार समितिका कोषाध्यक्ष रचना श्रेष्ठले अपराध गर्नेलाई कुनै पनि सर्तमा छाड्न नहुने बताइन् । कुचबाडियालाई प्रहरीले नियन्त्रणमा लिएर अनुसन्धान अघि बढाएको बाँके प्रहरी
Result model 2 should be:
घटनापछि बालिकाको मानसिक अवस्था ठिक नभएको र उपचार भइरहेको उनले बताइन् । महिला तथा बालबालिका टोल सुधार समितिका कोषाध्यक्ष रचना श्रेष्ठले अपराध गर्नेलाई कुनै पनि सर्तमा छाड्न नहुने बताइन् ।
you can split the string like this:
String newstr = "";
if (null != str && str.length() > 0 )
{
int endIndex1 = str.lastIndexOf("|");
int endIndex2 = str.lastIndexOf("।");
if (endIndex1 > endIndex2)
{
newstr = str.substring(0, endIndex1);
}else if(endIndex2 != -1) {
newstr = str.substring(0, endIndex2);
}
}

Format relative date to human readable format in Android using Android DateUtils API

I have a date field ( lastUpdated ). I want to translate this date to human readable format such as 'today', '1 day ago', '2 days ago', ...
I am using android.text.format.DateUtils API that included in Android library.
Here is my try:
DateUtils.getRelativeDateTimeString(context,
lastUpdated.getTime(),
DateUtils.DAY_IN_MILLIS,
DateUtils.WEEK_IN_MILLIS,
DateUtils.FORMAT_SHOW_YEAR);
Here is the output:
0 day ago, 12:00am
yesterday, 9:30am
2 days ago, 1:30pm
Sep 4, 12:30pm
The result I expected: ( No time information )
0 day ago --------- This should be 'today'
yesterday
2 days ago
Sep 4
NOTE that, if I clear time from lastUpdated. It will show '12:00am' for time information.
Anyone has any ideas? Is there any way to remove time from output?
Thank you!
You can use DateUtils.getRelativeTimeSpanString for that:
long now = System.currentTimeMillis();
DateUtils.getRelativeTimeSpanString(lastUpdated.getTime(), now, DateUtils.DAY_IN_MILLIS);
it seems like you want to have a custom handler for the times that are recent, and something more stdnard for dates that are further away. something like this would work:
public String getTimeDiff(long secondsTimeDiff)
{
long secondsInOneDay = 84600;
int maxDaysAgo = 10;
if ( secondsTimeDiff < secondsInOneDay)
{
return "today";
}
else if ( secondsTimeDiff < 2*secondsInOneDay)
{
return "yesterday";
}
else if ( secondsTimeDiff < maxDaysAgo*secondsInOneDay)
{
int days = (int) (secondsTimeDiff / secondsInOneDay);
return days + " days ago";
}
else
{
//use normal DateUtils logic here...
return "....";
}
}

Categories

Resources