I was doing an Android app that generates sales report for dates between the current date and seven days in the past. It worked fine, here's the code:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR,-7);
String currentDate = new SimpleDateFormat("dd-MM-yyyy").format(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
String sevenDayAgo = sdf.format(calendar.getTime());
Cursor weeklyIncome = db.getResult("select sum(price) as total_income from sales where date between '"+sevenDayAgo+"' and '"+currentDate+"'");
Cursor weeklyCost = db.getResult("select sum(purchase_price * quantity) as total_cost from sales where date between '"+sevenDayAgo+"' and '"+currentDate+"'");
Say for example currentDate = 31-08-2018 and sevenDayAgo = 24-08-2018 this all worked fine but when I change my system date to the next day which is the next month and currentDate becomes 01-09-2018 the query doesn't return anything from the database, it should have returned records between 25-08-2018 and 01-09-2018 which has seven days in between. Somehow the query doesn't work when the 7 days are in two different months. I don't know what's going on and how to fix it.
p.s. The date column in sales table is of type TEXT.
The problem is the format you're using for dates (dd-mm-yyyy) isn't in lexicographic order. The string '25-08-2018' compares greater than '01-09-2018' . x BETWEEN y AND z is equivalent to x >= y AND x <= z. That condition won't be true for dates in that range using your format (Remember, they're just strings. sqlite does not have a date type.
You should be using ISO-8601 formats, like yyyy-mm-dd. These will sort properly ('2018-08-25' < '2018-09-01') and will allow you to use the sqlite3 date and time functions on them.
Suppose user has entered the birth date in 31/08/2018 this format :
Parse it like :
String[] parts = BirthField.getText().toString().trim().split("/");
int CAL_DAY, CAL_MONTH, CAL_YEAR;
if(parts.length == 3)
{
CAL_DAY = Integer.parseInt(parts[0]);
CAL_MONTH = Integer.parseInt(parts[1]);
CAL_YEAR = Integer.parseInt(parts[2]);
}
You can check if user has entered a good date or not with :
if( CAL_DAY > 0 && CAL_DAY < 32 && CAL_MONTH > 0 && CAL_MONTH < 13 && CAL_YEAR > 1900 )
While storing in database table take below care :
Calendar CalendarEvent = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
CalendarEvent.set(Calendar.DATE, CAL_DAY);
CalendarEvent.set(Calendar.MONTH, CAL_MONTH - 1);
CalendarEvent.set(Calendar.HOUR_OF_DAY, Integer.parseInt(ScheduleTime) );
CalendarEvent.set(Calendar.MINUTE, 00);
CalendarEvent.set(Calendar.SECOND, 00);
SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.getDefault());
String DayConsidered = format.format(CalendarEvent.getTime());
Please note CAL_MONTH - 1 as system starts months from 0 to 11
While storing store in database in SystemTime like :
SYSTIME = CalendarEvent.getTimeInMillis();
While using it again retrieve it from database and initialise calendar event with it like :
Calendar CalendarEvent = Calendar.getInstance();
CalendarEvent.setTimeInMillis( Long.parseLong(SYSTIME) );
int CAL_DAY = CalendarEvent.get(Calendar.DAY);
CalendarEvent.set(Calendar.DATE, CAL_DAY - 7);
And it will start working for even if days / months / even you change years from any date; it will always show the date which is less than 7 days
Hope it helps and let me know how it works as i am answering it quick...
Edit : 2
Better and most efficient way which i am using in my project and working perfectly is :
Log.d("ADDING A MONTH :", "ADDING 1 MONTH....\n");
CalendarEvent.add(Calendar.MONTH, 1);
Log.d("NEGATING 7 DAYS :", "NEGATING 7 DAYS....\n");
CalendarEvent.add(Calendar.DATE, -7);
Related
I am using materialdatetimepicker to customise my calendar.
My requirement is I want to disable all dates from today and next 31 days.
What I have tried.
1 - Set the minimum date to Today - datePickerDialog.setMinDate(now);
2 - Maximum date to 31 days from today. - datePickerDialog.setMaxDate(cal);
3 - Disabled the dates in between. datePickerDialog.setDisabledDays(otherCalendars);
When I do step 1 2 and 3 together, the Calendar is not opened at all and app freezes.
When I do the steps (1,2) and 3 seperately I get the correct results. But I only want to display next 31days from now and disable them all.
Here is the code which I have tried.
Where am I getting this wrong? any help is much appreciated.
private DatePickerDialog datePickerDialog;
DateTime startDateTime = new DateTime();
DateTime endDateTime = new DateTime();
endDateTime = endDateTime.plusDays(31);
List<DateTime> otherDays = new ArrayList<>();
while (startDateTime.isBefore(endDateTime)) {
otherDays.add(startDateTime);
startDateTime = startDateTime.plusDays(1);
}
Calendar[] otherCalendars = new Calendar[otherDays.size()];
for (int count = 0; count < otherDays.size(); count++) {
otherCalendars[count] = otherDays.get(count).toGregorianCalendar();
}
datePickerDialog.setMinDate(now);
Calendar cal = Calendar.getInstance();
Date ddd = endDateTime.toDate();
cal.setTime(ddd);
datePickerDialog.setMaxDate(cal);
datePickerDialog.setDisabledDays(otherCalendars);
Thanks
R
I had the same issue and found solution for it here Disable whole week except weekend in calender
[disable-whole-week-except-weekends]
I used List with Calendar type List<Calendar> weekends = new ArrayList<>();
And fill it with days i want to disable.
I have a function with date calculations. It compares the database from and to date which I already retrieved, with the input from and to date which I am passing. While debugging, it showing wrong dates after assignment inside the for loop.(input and database dates) Below I shown the example with a image.
Function code:
/*String[] veh - vehicle name, String[] from - table from date array,
* String[] to - table to date array,String from1 - input from date, String to1 - input to date*/
private List getDateComparison(String[] veh, String[] from, String[] to,String from1, String to1) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:MM",Locale.ENGLISH);
Date table_from,table_to,input_from,input_to;
long diff=0,diff1=0,diff2=0,diff3=0;
int count=0,county=0;;
for(int i=0;i<veh.length;i++){
table_from=df.parse(from[i]);
table_to=df.parse(to[i]);
input_from=df.parse(from1);
input_to=df.parse(to1);
table_from=df.parse(df.format(table_from));
table_to=df.parse(df.format(table_to));
input_from=df.parse(df.format(input_from));
input_to=df.parse(df.format(input_to));
diff=table_from.getTime()-input_from.getTime();
diff1=table_from.getTime()-input_to.getTime();
diff2=input_from.getTime()-table_to.getTime();
diff3=input_to.getTime()-table_to.getTime();
if((diff > 0 && diff1>0) || (diff2 > 0 && diff3>0)){
count++;
removeAndAddList(veh[i],1);
Log.d("Date", " ok with from");
}
else {
county = 100;
removeAndAddList(veh[i],2);
}
}
return vehic;//= veh[0];
}
Function Screenshot while Debugging:
Edited:
Before I used the date format as,
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd",Locale.ENGLISH);
At that time the calculation worked perfectly. Now it was making some issues with the date format. I think my dateformat is doing something wrong inside the for loop. It was showing bigger dates after assigning the dates with dateformat. Where I did wrong?
The format you are using for the SDF is not correct
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:MM",Locale.ENGLISH);
as M means Month in year and you are using it as minutes.
change to HH:mm
... = new SimpleDateFormat("yyyy-MM-dd HH:mm",Locale.ENGLISH);
off-topic:
instead of using diff=table_from.getTime()-input_from.getTime(); you can make use of after() and before() methods for Date
you can compare dates as following (from your code):
if((diff > 0 && diff1>0) || (diff2 > 0 && diff3>0)){
will be:
if((table_from.after(input_from) && table_from.after(input_to))
|| (input_from.after(table_to) && input_to.after(table_to))){
now you can remove all the getTime() subtraction lines from the code (the 4 lines)
I have dates in a SQLite table that are stored in non-standard date formats. I need to be able to query by them. For example, records for today's date are 11/1/2015 in the "date" column and 2015-11-1 in the "sortDate" column.
My query needs to return the count of records from the past week. The following returns nothing: SELECT count(*) FROM Grades WHERE sortDate BETWEEN '2015-10-24' AND '2015-11-02'
I also get nothing from SELECT count(*) FROM Grades WHERE sortDate BETWEEN datetime('now', '-7 days') AND datetime('now')
I think the issue is that my dates are not padded to always have 2 month or date digits, as in YYYY-MM-DD. How would I query this existing data with these non-standard formats?
As Sqlite doesn't have a date type you will need to do string comparison to achieve this. For that to work you need to reverse the order - eg from dd/MM/yyyy to yyyyMMdd, using something like
where substr(column,7)||substr(column,4,2)||substr(column,1,2)
between '20101101' and '20101130'
I ended up getting all date strings from the database and dealing with them in Java. I just needed the count of how many entries there were within the past week, past two weeks, and past month. I wrote the following function to return those counts based on a provided ArrayList of strings.
Calendar today = Calendar.getInstance();
Calendar tomorrow = (Calendar) today.clone();
tomorrow.add(Calendar.DATE, 1);
Calendar backDateWeek = (Calendar) today.clone();
backDateWeek.add(Calendar.DATE, -7);
Calendar backDateTwoWeeks = (Calendar) today.clone();
backDateTwoWeeks.add(Calendar.DATE, -14);
Calendar backDateMonth = (Calendar) today.clone();
backDateMonth.add(Calendar.DATE, -30);
ArrayList<Calendar> calendarList = new ArrayList<Calendar>();
Calendar tmpCal;
String strSplit[];
int month;
int day;
int year;
int countWeek = 0;
int countTwoWeeks = 0;
int countMonth = 0;
for (String dateStr : dateStrings) {
strSplit = dateStr.split("/");
month = Integer.parseInt(strSplit[0]) - 1;
day = Integer.parseInt(strSplit[1]);
year = Integer.parseInt(strSplit[2]);
tmpCal = Calendar.getInstance();
tmpCal.set(Calendar.YEAR, year);
tmpCal.set(Calendar.MONTH, month);
tmpCal.set(Calendar.DAY_OF_MONTH, day);
if (tmpCal.after(backDateWeek) && tmpCal.before(tomorrow)) {
countWeek++;
countTwoWeeks++;
countMonth++;
} else if (tmpCal.after(backDateTwoWeeks) && tmpCal.before(tomorrow)) {
countTwoWeeks++;
countMonth++;
} else if (tmpCal.after(backDateMonth) && tmpCal.before(tomorrow)) {
countMonth++;
}
}
int[] countsArray = new int[3];
countsArray[0] = countWeek;
countsArray[1] = countTwoWeeks;
countsArray[2] = countMonth;
return countsArray;
I am using following code to convert timezone (GMT-3) to device local timezone.
int hour=17,minute=0,day=12,month=6,year=2014;
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
cal.set(year, (month-1), day,hour,minute);
cal.setTimeZone(TimeZone.getDefault());
Log.d("Time", cal.get(Calendar.DATE)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.YEAR)+" , "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" "+cal.get(Calendar.AM_PM));
My local timezone is GMT+5:30
Expected result is
Time 13/5/2014, 1:30 0
But I am getting the result
12/5/2014 , 13:30 1
Sorry for you, GregorianCalendar is sometimes the hell. Your problem is following:
If you immediately set the timezone after having set the fields for year, month etc. then this mutable calendar class will only shift the timezone retaining the already set fields containing the local time. Those fields for year, month etc. will NOT be recalculated. This behaviour causes a shift on the global timeline represented by cal.getTime(), too.
In order to force the calendar object to recalculate the fields you need to call a getter. Watch out for following code and especially remove the comment marks to see the effect.
int hour = 17, minute = 0, day = 12, month = 6, year = 2014;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
TimeZone tz1 = TimeZone.getTimeZone("GMT-3");
sdf.setTimeZone(tz1);
Calendar cal = new GregorianCalendar(tz1);
cal.set(year, (month - 1), day, hour, minute);
// System.out.println(sdf.format(cal.getTime()));
// System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
TimeZone tz2 = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz2);
cal.setTimeZone(tz2);
System.out.println(sdf.format(cal.getTime()));
System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
Output with comment-disabled lines:
2014-06-12T17:00+0530
Hour=17
Output with enabled lines after having removed the comment marks:
2014-06-12T17:00-0300
Hour=17
2014-06-13T01:30+0530
Hour=1
I am using jxl api to read an excel file in android. When I get a date like "30/11/2012" from excel, the LabelCell output shows me date as "11/30/12".
1) I need to get the output in dd/MM/yyyy format when reading the excel file, because it exists that way in excel, so I wouldn't want to unnecessarily convert it into another format. How to do that ?
2) After reading in the excel column's date, I generate 2 variables, one which has excel date - 20 days (lets call it excelMinus20) and another excel date + 10 days (lets call it excelPlus10.
Now, I would like to check going further, if the current system date (smartphone's date) >= excelMinus20 and current system date <= excelPlus10.
How to do this whole thing using java.text.Date ? I tried using joda time as well, but it's too complicated to use. Please guide me at least in the right direction.
Thanks in advance
Omkar Ghaisas
To parse your date from text format:
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = formatter.parse("30/11/2012");
More info : SimpleDateFormat doc
To substract days from your date:
public static Date substractDays(Date date, int days)
{
long millis = date.getTime();
long toSubstract = days * 1000 * 60 * 60 * 60 * 24;
// 1milli 1s 1m 1h 1d
return new Date(millis-toSubstract);
}
Adding some days would be the same, except replace - with +
To get back a String representation from a Date object:
DateFormat formatter = new SimpleDateFormat("...pattern...");
String formatedDate = formatter.format(date.getTime());
EDIT:
You could also do the Date adding/substracting with the method you suggested:
public static Date substractDays(Date date, int days)
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, -20 /*or +10*/);
return calendar.getTime();
}
If you want to check if a Date is in an interval, then:
public static boolean isInInterval(Date date, Date from, Date to)
{
return date.getTime()<to.getTime() && date.getTime() > from.getTime();
}