DB operation taking a lifetime to process - java
Okay, this is more of a speed issue. The problem is that I am fetching three fields from varied sources like Contacts, Facebook and Google plus. The three fields are a date, name and a contact image URi. The logic is such that each of the sources writes to a File, Contacts -- to file, Facebook - append to same file, Google Plus - append to same file. This operation is pretty fast and takes the normal time to execute. This creates my original Data source. Then from this file I fetch each record (Row with three fields) individually and do some calculations and write data pertaining to each record into three different database tables. While as this works pretty fast on a Quad Core phone, the process is too slow on a dual core phone. It takes around ten minutes to process 150 records on a dual core, takle four minutes to process 150 records on Quad core. I am perplexed as in how to increase the speed? Should I drop the idea of making a file as my original Data Source and instead switch to a Database table? What would be the fastest?
The code is as follows:
private class MagicCall extends AsyncTask<Void, String, String> {
int years;
long secon;
long min;
int hours;
int mon;
int days;
int weeks;
String CONTACT_ID,CONTACT_NAME,CONTACT_IMAGE_URI;
ProgressDialog Asycdialog = new ProgressDialog(LoaderClass.this);
#Override
protected void onPreExecute() {
boolean DIALOG_SHOW = true;
try{
BufferedReader br = null;
if(FLAG ==1){
br = new BufferedReader(new FileReader(getApplicationContext().getFilesDir()+"/xxxinders/fileone.txt"));
}else{
br = new BufferedReader(new FileReader(getApplicationContext().getFilesDir()+"/xxxinders/output.txt"));
}
if (br.readLine() == null) {
Toast.makeText(getApplicationContext(),"There are no contacts with Birthday details, try syncing with Facebook and/or Google", Toast.LENGTH_LONG).show();
DIALOG_SHOW = false;
}
}catch(Exception e){
System.out.println(e);
}
if(DIALOG_SHOW){
//Init the LoaderDialog
Asycdialog.setMessage("Working");
Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL);
Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
Asycdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
Asycdialog.setCancelable(false);
//Dialog Show
Asycdialog.show();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Editor editor = prefs.edit();
editor.putBoolean("async", true);
editor.commit();
super.onPreExecute();
}
protected void onPostExecute(String result) {
// hide the dialog
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, h:mm a");
String date = df.format(Calendar.getInstance().getTime());
SharedPreferences prefsx = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Editor editorx = prefsx.edit();
editorx.putString("refresh", date);
editorx.commit();
dbHelper.close();
Asycdialog.dismiss();
startActivity(new Intent(LoaderClass.this, MainActivity.class));
finish();
super.onPostExecute(result);
}
#Override
protected String doInBackground(Void... args) {
dbHelper = new DBAdapter(getApplicationContext());
dbHelper.open();
int i=0;
int lines = 0;
// int prog = fetchAdhoc();
String progress = null;
String dateToInsert;
try{
BufferedReader reader;
if(FLAG ==1){
reader = new BufferedReader(new FileReader(getApplicationContext().getFilesDir()+"/xxxinders/fileone.txt"));
}else{
reader = new BufferedReader(new FileReader(getApplicationContext().getFilesDir()+"/xxxinders/output.txt"));
}
while (reader.readLine() != null) lines++;
reader.close();
}catch(Exception e){
}
Cursor c = dbHelper.fetchAdhoc();
ADHOC_COUNT = (c.getCount());
lines=lines+ADHOC_COUNT;
dbHelper.NotificationDrop();
if (c.moveToFirst()) {
do {
try{
String name = c.getString(c.getColumnIndexOrThrow("Name"));
String displayBirthday = c.getString(c.getColumnIndexOrThrow("DOB"));
String imageData = c.getString(c.getColumnIndexOrThrow("ImageData"));
String primaryAdhoc = c.getString(c.getColumnIndexOrThrow("_id"));
//CONTACT_ID,CONTACT_NAME,CONTACT_IMAGE_URI
CONTACT_ID = primaryAdhoc;
CONTACT_NAME = toTitleCase(name);
CONTACT_IMAGE_URI = imageData;
dateToInsert = displayBirthday;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(dateToInsert);
java.sql.Date dx = new java.sql.Date(date.getTime());
Date key = dx;
years = getDiffYear(key); // For years elapsed
secon = seconds(key); // for seconds elapsed
min = seconds(key) / 60; // For minutes elapsed
hours = (int) (seconds(key) / 60) / 60; // For hours elapsed
mon = months(String.valueOf(key)); // for months elapsed
days = daysElapsed(key); // Days elapsed
weeks = daysElapsed(key) / 7; // For weeks
System.out.println(lines);
progress = ("" + (CONTACT_NAME) + "\n"+ i + " of " + lines + " Contacts");
dbHelper.insert(dateToInsert, CONTACT_NAME, String.valueOf(days), String.valueOf(hours), CONTACT_IMAGE_URI, String.valueOf(min),String.valueOf(mon), String.valueOf(secon), CONTACT_ID, String.valueOf(weeks), String.valueOf(years));
int PRIMARY_ID = dbHelper.getPrimaryId(); // Fetch the PrimaryId (_id) of the above inserted row, its the Foreign key for Notification and SpecialNotifications Table.
String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID); // Same as above, but fetches the Name field of the last inserted row.
//=========================================================================
//**Database Insertions Notifications Table/ SpecialNotifications Table**
//=========================================================================
//=======================================================================================//
//Regular intervals DB Insertions:
//======================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//======================================================================================//
//==============================
//For Months
//==============================
intCal.monthsNotify(mon, dateToInsert);
int monSpecial = intCal.getMonthRegular();
Date dateMonReg = intCal.getMonRegDate();
dbHelper.insertNotifications(1, convertDate(dateMonReg), 0, monSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For Weeks
//===============================
intCal.weeksToNotify(weeks,dateToInsert);
int weekSpecial = intCal.getWeekRegular();
Date dateWeekReg =intCal.getWeekRegDate();
dbHelper.insertNotifications(2, convertDate(dateWeekReg), 0, weekSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For Days
//===============================
intCal.daysToNotify(days, dateToInsert);
int daysSpecial= intCal.getDaysRegular();
Date dateDaysReg = intCal.getDaysRegDate();
dbHelper.insertNotifications(3, convertDate(dateDaysReg), 0, daysSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For minutes
//===============================
intCal.minutesToNotify(min,dateToInsert);
long minutesSpecial= intCal.getMinutesRegular();
Date dateMinsReg = intCal.getMinutesRegDate();
dbHelper.insertNotifications(4, convertDate(dateMinsReg), 0,(int) minutesSpecial,FOREIGN_KEY,PRIMARY_ID);
//==============================
//For Years
//==============================
intCal.yearsToNotify(years, dateToInsert);
int yearsSpecial = intCal.getYearsRegular();
Date dateYearsReg = intCal.getYearsRegDate();
dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID);
//=============================
//For Seconds
//=============================
intCal.secondsToNotify(secon, dateToInsert);
long secondsSpecial= intCal.getSecondsRegular();
Date dateSecondsReg = intCal.getSecondsRegDate();
dbHelper.insertNotifications(6, convertDate(dateSecondsReg), 0, secondsSpecial,FOREIGN_KEY,PRIMARY_ID);
//=============================
//For Hours
//=============================
intCal.hoursToNotify(hours, dateToInsert);
int hoursSpecial= intCal.getHoursRegular();
Date dateHoursReg= intCal.getHoursRegDate();
dbHelper.insertNotifications(7, convertDate(dateHoursReg), 0, hoursSpecial,FOREIGN_KEY,PRIMARY_ID);
//============================================================================================//
//Special Intervals
//============================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//For Years
intCal.specialIntervalYears(years, dateToInsert);
int yearsOnceSpecial =intCal.getYearsSpecial();
Date dateYearsSpecial = intCal.getYearsSpDate();
dbHelper.insertSpecialNotifications(5, convertDate(dateYearsSpecial), yearsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Months
intCal.specialIntervalMonths(mon,dateToInsert);
int monthsOnceSpecial= intCal.getMonthsSpecial();
Date dateMonthsSpecial = intCal.getMonthsSpDate();
dbHelper.insertSpecialNotifications(1, convertDate(dateMonthsSpecial), monthsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Weeks
intCal.specialIntervalsWeeks(weeks,dateToInsert);
int weeksOnceSpecial= intCal.getWeeksSpecial();
Date dateWeeksSpecial = intCal.getWeeksSpDate();
dbHelper.insertSpecialNotifications(2, convertDate(dateWeeksSpecial), weeksOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Days
intCal.specialIntervalsDays(days, dateToInsert);
int daysOnceSpecial= intCal.getDaysSpecial();
Date dateDaysSpecial = intCal.getDaysSpDate();
dbHelper.insertSpecialNotifications(3, convertDate(dateDaysSpecial), daysOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Hours
intCal.specialIntervalsHours(hours,dateToInsert);
int hoursOnceSpecial= intCal.getHoursSpecial();
Date dateHoursSpecial = intCal.getHoursSpDate();
dbHelper.insertSpecialNotifications(7, convertDate(dateHoursSpecial), hoursOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Minutes
intCal.specialIntervalMinutes(min,dateToInsert);
long minutesOnceSpecial= intCal.getMinutesSpecial();
Date dateMinutesSpecial= intCal.getMinutesSpDate();
dbHelper.insertSpecialNotifications(4, convertDate(dateMinutesSpecial), (int)minutesOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Seconds
intCal.specialIntervalsSeconds(secon,dateToInsert);
long secondsOnceSpecial= intCal.getSecondsSpecial();
Date dateSecondsSpecial= intCal.getSecondsSpDate();
dbHelper.insertSpecialNotifications(6, convertDate(dateSecondsSpecial), secondsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
i++;
}catch(Exception e){
}
publishProgress(progress);
Asycdialog.setMax(lines);
Asycdialog.incrementProgressBy(1);
}while(c.moveToNext());
}
//
// Dear maintainer:
//
// Once you are done trying to 'optimise' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 0;
//
//int i=0;
File toRead = null;
try{
if(FLAG ==1){
toRead=new File(getApplicationContext().getFilesDir()+"/xxxinders/fileone.txt");
}else{
toRead=new File(getApplicationContext().getFilesDir()+"/xxxinders/output.txt");
}
FileInputStream fis=new FileInputStream(toRead);
Scanner sc=new Scanner(fis);
String currentLine;
while(sc.hasNextLine()){
currentLine=sc.nextLine();
StringTokenizer st=new StringTokenizer(currentLine,"=",false);
CONTACT_NAME = toTitleCase(st.nextToken());
if(CONTACT_NAME.contains("'")){
CONTACT_NAME = CONTACT_NAME.replace("'", "");
}
// *********
String listStr = st.nextToken();
String cut = listStr.substring(1, listStr.length() - 1);
String[] array = cut.split(",");
CONTACT_ID = (array[0].trim());
String dateStr = (array[1].trim());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(dateStr);
java.sql.Date dx = new java.sql.Date(date.getTime());
Date key = dx;
dateToInsert = String.valueOf(dx);
CONTACT_IMAGE_URI = (array[2].trim());
if (isCancelled()) {
break;
}
progress = ("" + Character.toUpperCase(CONTACT_NAME.charAt(0)) + CONTACT_NAME.substring(1) + "\n"+i + " of " + lines + " Contacts"); // Progress displayed here.
years = getDiffYear(key); // For years elapsed
secon = seconds(key); // for seconds elapsed
min = seconds(key) / 60; // For minutes elapsed
hours = (int) (seconds(key) / 60) / 60; // For hours elapsed
mon = months(String.valueOf(key)); // for months elapsed
days = daysElapsed(key); // Days elapsed
weeks = daysElapsed(key) / 7; // For weeks
//===============================================================================================================
if (dateToInsert.contains("0001-") == true){ //Special Case, we added 0001 to Birthdays Which Have NO Year field.
//===========================================================================================================
dbHelper.insert(dateToInsert, CONTACT_NAME, "","", CONTACT_IMAGE_URI, "", "", "", CONTACT_ID, "", ""); // All other fields will be empty, because we don't have a Year.
int PRIMARY_ID = dbHelper.getPrimaryId();
String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID);
//=====================================================================================================
//In this case we are only interested in fetching the year alert for next birthday of this contact -->
//=====================================================================================================
intCal.yearsToNotify(years, dateToInsert);
int yearsSpecial = intCal.getYearsRegular();
Date dateYearsReg = intCal.getYearsRegDate();
dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID);
}
//=========================================================================
//Case when all the Date fields exist and we set up notifications --->
//=========================================================================
else if(dateToInsert != "null" && dateToInsert.contains("0001-") != true){
dbHelper.insert(dateToInsert, CONTACT_NAME, String.valueOf(days), String.valueOf(hours), CONTACT_IMAGE_URI, String.valueOf(min),String.valueOf(mon), String.valueOf(secon), CONTACT_ID, String.valueOf(weeks), String.valueOf(years));
int PRIMARY_ID = dbHelper.getPrimaryId(); // Fetch the PrimaryId (_id) of the above inserted row, its the Foreign key for Notification and SpecialNotifications Table.
String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID); // Same as above, but fetches the Name field of the last inserted row.
//=========================================================================
//**Database Insertions Notifications Table/ SpecialNotifications Table**
//=========================================================================
//=======================================================================================//
//Regular intervals DB Insertions:
//======================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//======================================================================================//
//==============================
//For Months
//==============================
intCal.monthsNotify(mon, dateToInsert);
int monSpecial = intCal.getMonthRegular();
Date dateMonReg = intCal.getMonRegDate();
dbHelper.insertNotifications(1, convertDate(dateMonReg), 0, monSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For Weeks
//===============================
intCal.weeksToNotify(weeks,dateToInsert);
int weekSpecial = intCal.getWeekRegular();
Date dateWeekReg =intCal.getWeekRegDate();
dbHelper.insertNotifications(2, convertDate(dateWeekReg), 0, weekSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For Days
//===============================
intCal.daysToNotify(days, dateToInsert);
int daysSpecial= intCal.getDaysRegular();
Date dateDaysReg = intCal.getDaysRegDate();
dbHelper.insertNotifications(3, convertDate(dateDaysReg), 0, daysSpecial,FOREIGN_KEY,PRIMARY_ID);
//===============================
//For minutes
//===============================
intCal.minutesToNotify(min,dateToInsert);
long minutesSpecial= intCal.getMinutesRegular();
Date dateMinsReg = intCal.getMinutesRegDate();
dbHelper.insertNotifications(4, convertDate(dateMinsReg), 0,(int) minutesSpecial,FOREIGN_KEY,PRIMARY_ID);
//==============================
//For Years
//==============================
intCal.yearsToNotify(years, dateToInsert);
int yearsSpecial = intCal.getYearsRegular();
Date dateYearsReg = intCal.getYearsRegDate();
dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID);
//=============================
//For Seconds
//=============================
intCal.secondsToNotify(secon, dateToInsert);
long secondsSpecial= intCal.getSecondsRegular();
Date dateSecondsReg = intCal.getSecondsRegDate();
dbHelper.insertNotifications(6, convertDate(dateSecondsReg), 0, secondsSpecial,FOREIGN_KEY,PRIMARY_ID);
//=============================
//For Hours
//=============================
intCal.hoursToNotify(hours, dateToInsert);
int hoursSpecial= intCal.getHoursRegular();
Date dateHoursReg= intCal.getHoursRegDate();
dbHelper.insertNotifications(7, convertDate(dateHoursReg), 0, hoursSpecial,FOREIGN_KEY,PRIMARY_ID);
//============================================================================================//
//Special Intervals
//============================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//For Years
intCal.specialIntervalYears(years, dateToInsert);
int yearsOnceSpecial =intCal.getYearsSpecial();
Date dateYearsSpecial = intCal.getYearsSpDate();
dbHelper.insertSpecialNotifications(5, convertDate(dateYearsSpecial), yearsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Months
intCal.specialIntervalMonths(mon,dateToInsert);
int monthsOnceSpecial= intCal.getMonthsSpecial();
Date dateMonthsSpecial = intCal.getMonthsSpDate();
dbHelper.insertSpecialNotifications(1, convertDate(dateMonthsSpecial), monthsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Weeks
intCal.specialIntervalsWeeks(weeks,dateToInsert);
int weeksOnceSpecial= intCal.getWeeksSpecial();
Date dateWeeksSpecial = intCal.getWeeksSpDate();
dbHelper.insertSpecialNotifications(2, convertDate(dateWeeksSpecial), weeksOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Days
intCal.specialIntervalsDays(days, dateToInsert);
int daysOnceSpecial= intCal.getDaysSpecial();
Date dateDaysSpecial = intCal.getDaysSpDate();
dbHelper.insertSpecialNotifications(3, convertDate(dateDaysSpecial), daysOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Hours
intCal.specialIntervalsHours(hours,dateToInsert);
int hoursOnceSpecial= intCal.getHoursSpecial();
Date dateHoursSpecial = intCal.getHoursSpDate();
dbHelper.insertSpecialNotifications(7, convertDate(dateHoursSpecial), hoursOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Minutes
intCal.specialIntervalMinutes(min,dateToInsert);
long minutesOnceSpecial= intCal.getMinutesSpecial();
Date dateMinutesSpecial= intCal.getMinutesSpDate();
dbHelper.insertSpecialNotifications(4, convertDate(dateMinutesSpecial), (int)minutesOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
//For Seconds
intCal.specialIntervalsSeconds(secon,dateToInsert);
long secondsOnceSpecial= intCal.getSecondsSpecial();
Date dateSecondsSpecial= intCal.getSecondsSpDate();
dbHelper.insertSpecialNotifications(6, convertDate(dateSecondsSpecial), secondsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);
writeToSD();
}
publishProgress(progress);
Asycdialog.setMax(lines);
Asycdialog.incrementProgressBy(1);
i++;
}
writeToSD();
}catch (Exception e){
System.out.println(e);
} finally{
dbHelper.close();
}
return "";
}
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
Asycdialog.setMessage("" + values[0]);
}
}
Edit: I found something useful Here
Test your ideas with this and this it allows you to check which part of your code is slow so you fix it.
You can store the informations in a local database instead a textfile. It should work much faster than with the textfile and you still can generate the textfile from the local database.
Related
Calculate days, months, and years elapsed between start and end date [duplicate]
This question already has answers here: Organise number of days into separate sections for year, months, days, hours. Java (2 answers) Calculate date/time difference in java [duplicate] (17 answers) Closed 4 years ago. i am working on date calculation application like windows 10 calculator where you select start and end date and calculate days month and year public String differenceInDates(){ Date start_date = convertStringToDate("2017-04-24"); Date end_date = convertStringToDate("2018-07-24"); long different = this.end_date.getTime() - this.start_date.getTime(); long millisInSeconds = 1000; long millisInMinutes = millisInSeconds * 60; long millisInHours = millisInMinutes * 60; long millisInDay = millisInHours *24; long elapsedDays = different / millisInDay; different = different % millisInDay; long elapsedHours = different / millisInHours; different = different % millisInHours; long elapsedMinutes = different / millisInMinutes; different = different % millisInMinutes; long elapsedSeconds = different / millisInSeconds; if (elapsedHours == 0){ return String.valueOf("days"+elapsedDays+":"+":"+elapsedMinutes+":"+elapsedSeconds); } if (elapsedMinutes == 0){ return String.valueOf("days"+elapsedDays+":"+":"+elapsedHours+":"+elapsedSeconds); } if (elapsedHours == 0 && elapsedMinutes == 0){ return String.valueOf("days"+elapsedDays); } return String.valueOf("days"+elapsedDays+":"+" Hours"+elapsedHours+":"+" Minutes"+elapsedMinutes+":"+elapsedSeconds); } private Date convertStringToDate(String strDate) throws ParseException { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = simpleDateFormat.parse(strDate); return date; } i want answer like this 1 year 3 months
java.time If you can use LocalDate & Period, then it's quite simple: LocalDate date1 = LocalDateTime.of(2018, Month.SEPTEMBER, 2, 13, 40); LocalDate date2 = LocalDateTime.of(2018, Month.SEPTEMBER, 2, 13, 40); Period period = Period.between(date1, date2); System.out.println(period.getYears() + " year " + period.getMonths() + " months");
you can use this code: SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); String CURRDATE = "16-07-1991"; String EFFDATE = "28-08-2018"; Date startdate = null; Date enddate = null; try { startdate = formatter.parse(CURRDATE); enddate = formatter.parse(EFFDATE); } catch (ParseException e) { e.printStackTrace(); } Calendar startCalendar = new GregorianCalendar(); startCalendar.setTime(startdate); Calendar endCalendar = new GregorianCalendar(); endCalendar.setTime(enddate); int monthCount = 0; int firstDayInFirstMonth = startCalendar.get(Calendar.DAY_OF_MONTH); startCalendar.set(Calendar.DAY_OF_MONTH, 1); endCalendar.add(Calendar.DAY_OF_YEAR, -firstDayInFirstMonth + 1); while (!startCalendar.after(endCalendar)) { startCalendar.add(Calendar.MONTH, 1); ++monthCount; } startCalendar.add(Calendar.MONTH, -1); --monthCount; int remainingDays = 0; while (!startCalendar.after(endCalendar)) { startCalendar.add(Calendar.DAY_OF_YEAR, 1); ++remainingDays; } startCalendar.add(Calendar.DAY_OF_YEAR, -1); --remainingDays; int lastMonthMaxDays = endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); if (remainingDays >= lastMonthMaxDays) { ++monthCount; remainingDays -= lastMonthMaxDays; } int diffMonth = monthCount % 12; int diffYear = monthCount / 12; int diffDay = remainingDays; System.out.println(diffYear + " Year(s) and " + diffMonth + " Month(s) and " + diffDay + " Day(s)"); The result is: 27 Year(s) and 1 Month(s) and 12 Day(s)
Android weekly event not being set for all the days
I have searched extensively on SO and various forums and I can't figure this one out. I'm generating a reccuring event in Android calendar. Sometimes it works flawlessly and sometimes it sets it only for the upcoming 4-5 weeks and then stops. What precisely am I doing wrong here? This is my function that adds an event in the calendar private void addToCalendar(int DAY_WEEK, String TITLE, String DESC, String LOC, int hour_s, int min_s, int hour_e, int min_e) { Uri uri = Calendars.CONTENT_URI; String[] projection = new String[]{ Calendars._ID, Calendars.ACCOUNT_NAME, Calendars.CALENDAR_DISPLAY_NAME, Calendars.NAME, Calendars.CALENDAR_COLOR }; // Construct event details long startMillis = 0; long endMillis = 0; int year = Calendar.getInstance().get(Calendar.YEAR); int month = Calendar.getInstance().get(Calendar.MONTH); Calendar now = Calendar.getInstance(); int day = now.get(Calendar.DAY_OF_WEEK); int daym = now.get(Calendar.DAY_OF_MONTH); int start_day = 0; if (day != DAY_WEEK) { start_day = daym - (day - DAY_WEEK); //Toast.makeText(this, Integer.toString(start_day), Toast.LENGTH_LONG).show(); } else { start_day = daym; } Calendar beginTime = Calendar.getInstance(); beginTime.set(year, month, start_day, hour_s, min_s); startMillis = beginTime.getTimeInMillis(); Calendar endTime = Calendar.getInstance(); endTime.set(year, month, start_day, hour_e, min_e); endMillis = endTime.getTimeInMillis(); Calendar endRRule = Calendar.getInstance(); endRRule.add(Calendar.MONTH, 3); long endRRuleMillis = endRRule.getTimeInMillis(); // Insert Event ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); TimeZone timeZone = TimeZone.getDefault(); values.put(Events.DTSTART, startMillis); values.put(Events.DTEND, endMillis); values.put(Events.EVENT_TIMEZONE, timeZone.getID()); values.put(Events.RRULE, "FREQ=WEEKLY;"); values.put(Events.HAS_ALARM, 1); values.put(Events.TITLE, TITLE); values.put(Events.DESCRIPTION, DESC); values.put(Events.EVENT_LOCATION, LOC); values.put(Events.CALENDAR_ID, 1); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, 101); } uri = cr.insert(CalendarContract.Events.CONTENT_URI, values); // Retrieve ID for new event String eventID = uri.getLastPathSegment(); ContentValues reminders = new ContentValues(); reminders.put(CalendarContract.Reminders.EVENT_ID, eventID); reminders.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); reminders.put(CalendarContract.Reminders.MINUTES, 15); Uri uri2 = cr.insert(CalendarContract.Reminders.CONTENT_URI, reminders); } And I am calling it from another function which I shortened in order to improve code readability This loop goes through all of the SQL results from the local database while (c.moveToNext()) { Log.d("COURSE NAME", c.getString(c.getColumnIndex("course_name"))); final ListModelSchedules sched = new ListModelSchedules(); ... if (setDay != 0 && title != null && desc != null && room != null && setStartTime != 0 && setEndTime != 0) { addToCalendar(setDay, title, desc, room, setStartTime, 0, setEndTime, 0); } } It adds the event correctly, but instead of it being repeaten indefinitely, it sometimes stops after 4-5 weeks. What am I doing wrong here? If I set RRule's UNTIL=timestamp, it breaks and adds nothing to the calendar. Any help would be appreciated. EDIT: I just noticed that it actually adds all those events for all of the days. But it shows after you manually select a refresh option inside the calendar app. Is this something that can be solved or is it just the way calendar app is designed?
Unable to display out the remaining date
My program will get data from database and show it in a Listview. Now I get the date from database and compare it with my current date and count the remaining day. I successfully got the data and show it in a listview, but my remaining day code is not working. Any help will be appreciated! List<HashMap<String,Object>> aList = newArrayList<HashMap<String,Object>>(); for (int i = 0; i<records.size(); i++) { HashMap<String, Object> hm = new HashMap<String, Object>(); hm.put("txt", records.get(i).getAssname()); hm.put("txt2", records.get(i).getAssTime()); String ez = records.get(i).getAssTime(); Calendar today = Calendar.getInstance(); //count the remain day try { SimpleDateFormat dd = new SimpleDateFormat("dd/M/yyyy"); Date date1= dd.parse(ez); Date date2 = today.getTime(); long diff = Math.abs(date1.getTime() - date2.getTime()); long diffDays = diff / (24 * 60 * 60 * 1000); hm.put("txt3", String.valueOf(diffDays)); } catch (Exception e1) { } aList.add(hm); } // Keys used in Hashmap String[] from = {"txt","txt2","txt3"}; // Ids of views in listview_layout int[] to = { R.id.assigment_name,R.id.assigment_ATime, R.id.assigment_remain}; // Instantiating an adapter to store each items // R.layout.listview_layout defines the layout of each item SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.view_assignment_entry, from, to); What's wrong with my code ?
You can try change long diff = Math.abs(date1.getTime() - date2.getTime()); long diffDays = diff / (24 * 60 * 60 * 1000); to long diff = date1.getTime() - date2.getTime(); long diffDays = Math.abs(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
final long DAY_MILLIS = 24* 60 * 60*1000 ; int Days = (int) ((date_1.getTime() - date_2.getTime())/ DAY_MILLIS ); or you can use Joda time library for Java. Days d = Days.daysBetween(startDate, endDate); int days = d.getDays(); I hope it will help you...!
Android check days between two day-times
Hello everyone i try to check between days two daytimes i have for example 12/10/2014 and 12/15/2015 datetimes.I wrote some code witch can to check different days between there two daytimes this is a my source public String getDateDiffString(Date dateOne, Date dateTwo) { long timeOne = dateOne.getTime(); long timeTwo = dateTwo.getTime(); long oneDay = 1000 * 60 * 60 * 24; long delta = (timeTwo - timeOne) / oneDay; if (delta > 0) { return String.valueOf(delta); } else { delta *= -1; return String.valueOf(delta); } } this code working perfect but i want to increase days for example 12/10/2014, 12/11,2014.....12/20/2014 between first and second daytimes.i i also wrote code but result is between first date and second days -1(between 12/19/2014) this is a my source SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy"); Date _d; try { SimpleDateFormat new_df = new SimpleDateFormat("d MMM"); _d = df.parse(timeInfo.getTimeformat().get(0)); Date _d1 = df.parse(timeInfo.getEndTimeFormat().get(0)); String datetimeis = getDateDiffString(_d1, _d); int differentdays = Integer.parseInt(datetimeis); Log.e("Different is ", "" + differentdays); for (int k = 0; k < differentdays; k++) { String datetimeformat = dateFormatter(timeInfo.getStartTimePeriod().get(0)); Date datetime = new_df.parse(datetimeformat); Calendar cal = Calendar.getInstance(); cal.setTime(datetime); cal.add(Calendar.DATE, k); datetime = cal.getTime(); String ttime = new_df.format(datetime); ApishaDaysAdapter.add(ttime); ApishaHollsAdapter.add(timeInfo.getHole()); String start_time = timeInfo.getTime(); start_time = start_time.replace(",", "\n"); ApishaTimesAdapter.add(start_time); timeInfo.setStartTimePeriod(ttime); System.out.println(ttime); } } catch (ParseException e) { e.printStackTrace(); } } how i can solve my problem?if anyone knows solution please help me i want to increase days [12 -20] and not [12-19)
Joda Time cannot subtract one hour
In my android program, I have a spinner that allows the user to select different times. Each selection is processed with Joda time to subtract the minutes. It works fine for minutes 0 to 59 and 61 and greater. However, when 60 minutes is subtracted, the time is not updated, and the original time is shown. How do I get Joda time to subtract 60 minutes? Spinner: public class MyOnItemSelectedListener implements OnItemSelectedListener { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id1) { String mins = parent.getItemAtPosition(pos).toString(); int intmins=0; // process user's selection of alert time if(mins.equals("5 minutes")){intmins = 5;} if(mins.equals("10 minutes")){intmins = 10;} if(mins.equals("20 minutes")){intmins = 20;} if(mins.equals("30 minutes")){intmins = 30;} if(mins.equals("40 minutes")){intmins = 40;} if(mins.equals("50 minutes")){intmins = 50;} if(mins.equals("60 minutes")){intmins = 60;} if(mins.equals("120 minutes")){intmins = 120;} String stringMinutes=""+intmins; setAlarm(intmins, stringMinutes); } else { } public void onNothingSelected(AdapterView parent) { mLocationDisplay.setText(" " + location); } } public void setAlarm(int intmins, String mins) { // based alarm time on start time of event. TODO get info from database. String currentDate; SimpleDateFormat myFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); Date date1 = null; DateTime dt; currentDate = eventdate + " " + startTimeMilitary;// startTimeMilitary; try { date1 = myFormat.parse(currentDate); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } dt = new DateTime(date1); long dateInMillis = dt.getMillis(); String sDateInMillis = Long.toString(dateInMillis); // subtract the selected time from the event's start time String newAlertTime = subtractTime(dt, intmins); newAlertTime = subtractTime(dt, intmins); //......} public String subtractTime(DateTime dt, int minusTime) { DateTime greaterDate; greaterDate = dt.minusMinutes(minusTime); // newAlertTime is in UTC format String newAlertTime = greaterDate.toString(); long alertInMillis = greaterDate.getMillis(); String sAlertInMillis = Long.toString(alertInMillis); // ////new alert time is a stirng setStringAlertInMillis(sAlertInMillis); return newAlertTime; }
1) Remove hardcode. Use final String mins = parent.getItemAtPosition(pos).toString(); final Pattern minutes = Pattern.compile("([0-9]+) minutes"); final Matcher m = minutes.matcher(mins); String stringMinutes = "0"; if (mins.matches()) { stringMinutes = m.group(1); } setAlarm(Integer.parseInt(stringMinutes), stringMinutes); instead of your hardcode String mins = parent.getItemAtPosition(pos).toString(); // your hardcode is here setAlarm(Integer.parseInt(stringMinutes), stringMinutes); 2) Use DateTimeFormatter instead of SimpleDateFormatter You get java Date using SimpleDateFormatter and create DateTime by this date. DateTimeFormatter formatter = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss"); dt = formatter.parseDateTime(currentDate); 3) Joda works well in this code no problem with Joda. String subtractTime(DateTime dt, int minusTime) should works well. Debug you code, problem is before if(mins.equals("5 minutes")){intmins = 5;} if(mins.equals("10 minutes")){intmins = 10;} //...