Setting the time for both DatePicker fields in a DatePickerDialog - android

I am trying to create a DatePickerDialog when a certain TextView is clicked, and then set the date picked to be that TextView. I have gotten this to work, but when the DatePickerDialog is shown, the dates for left DatePicker are correctly set to the current date, while the calendar on the right is set to November 2100. How can I access the field of calendar and set its date?
Here is a link to an image of what I am talking about, but is not from my application exactly.
http://i1023.photobucket.com/albums/af358/shaikhhamadali/typesofdialog_4_zps078711ac.png
So, I am talking about the calendar on the right that does not start on the current date. I would like to know how to access it? If I'm not mistaken, this calendar will only show on tablets, so is there a "safe" way to do this where running it on a phone would not cause any problems?
Here is the code from my DatePickerFragment innerclass onCreateDialog method
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, year, month, day);
datePickerDialog.setTitle("Enter date");
datePickerDialog.getDatePicker().setMinDate(Calendar.getInstance().getTimeInMillis() / 86400000L * 86400000L);
return datePickerDialog;
}
Thank you for any help!
UPDATE:
Update: I have tried adding accessing the CalendarView through both, but the CalendarView still starts up at Nov 2100
datePickerDialog.getDatePicker().getCalendarView().setDate(Calendar.getInstance().getTimeInMillis() / 86400000L *86400000L);
datePickerDialog.getDatePicker().getCalendarView().setMinDate(Calendar.getInstance().getTimeInMillis() / 86400000L 86400000L);

Solution
This long answer (to a question about practically the same bug) suggests a workaround for this issue.
Part of it quoted here:
formatDateRange() does not work past 2038.
Workaround #1
class DatePickerDialog1964 extends DatePickerDialog {
DatePickerDialog1964(Context c) {
super(c, null, 2013, 4, 21);
#SuppressWarnings("deprecation")
Date min = new Date(2013-1900, 4, 21);
DatePicker p = getDatePicker();
CalendarView cv = p.getCalendarView(); // should check for null
long cur = cv.getDate();
int d = cv.getFirstDayOfWeek();
p.setMinDate(min.getTime());
cv.setDate(cur + 1000L*60*60*24*40);
cv.setFirstDayOfWeek((d + 1) % 7);
cv.setDate(cur);
cv.setFirstDayOfWeek(d);
}
}
Workaround #2 I actually used
// Calendar view is a cascade of bugs.
// Work around that by explicitly disabling it.
datePicker.setCalendarViewShown(false);
My Deduction
By elimination, we can deduce that the line datePickerDialog.getDatePicker().setMinDate(Calendar.getInstance().getTimeInMillis() / 86400000L * 86400000L); is causing the November 2100 error.
(UNIX time / 86400000L) * 86400000L --I guess it's supposed to take advantage of rounding to produce a 'full' day. Beware of it rounding to the same day if the current time is after noon, the previous day if before. It isn't chopping after the floating point.
About the updated part:
Even calling setMinDate then setDate isn't really solving anything -- The problem that caused the Nov 2100 error will persist, because the updated line's effect is executed by the original code.
Then I looked around, and I found the above linked answer.
I guess CalendarView is stuffed with bugs.
There appears to be another NumberPicker bug where the previous month and date and shown sometimes, even if not accessible. They disappear when we try to access them.
P.S: I know this is late, but since the OP didn't provide any solution, an analysis might be helpful to somebody.

Related

How do you Disable Certain Days on a Datepicker - Android

I'm trying to implement a datepicker but I need to disable some days. For example, I do not want the user to pick Friday and Saturday. I read in other posts that I need to use this library, but I still do not know how it works and how to do it in Kotlin. Someone help me plz.
In the library documentation there is mentioned that how to use select able days and how to disable certain days. For both purpose you have to pass the array of days to the respective methods.
For example if you want to select certain days only you have to pass the array of days to the method. To create the days arraylist use following code
Calendar[] days = new Calendar[13];
for (int i = -6; i < 7; i++) {
Calendar day = Calendar.getInstance();
day.add(Calendar.DAY_OF_MONTH, i * 2);
days[i + 6] = day;
}
Now after initializing the datpicker dialog call the method to select the days or disable days.
DatePickerDialog datePickerDialog = DatePickerDialog.newInstance(MainActivity.this,
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH));
datePickerDialog.setDisabledDays(days)

xamarin android DatePickerDialog set mini date

I'm using DatePickerDialog and i want to hide every date before today.
I can hide previous month and year using this code:
dialog.DatePicker.MinDate = new Java.Util.Date().Time - 1000;
But it's not working like i want. Days between 1st of june and today are disabled (gray) but we still can click on them and dismiss the dialog by clicking on the positive button.
Does someone has a solution to realy disabled them ? or at least avoid dismiss the dialog?
You need to give MinDate the number of milliseconds between your minimum date (in your case today) and January 1st 1970, so:
dialog.DatePicker.MinDate = (long)(DateTime.Today.Date - new DateTime(1970, 1, 1)).TotalMilliseconds;
This should prevent users from selecting any earlier dates.
Try changing the mindate to date now?
dateTimePicker1.MinDate = DateTime.Now;
Something like that should work. :)
//for lesser than today
dialog.DatePicker.MinDate = Java.Lang.JavaSystem.CurrentTimeMillis();
//for greater than today
dialog.DatePicker.MaxDate = Java.Lang.JavaSystem.CurrentTimeMillis();
This solved mine :)

Why is this generating 3913 as the year

I wrote some code that I am try to use as a comparison for a subscription so this piece of code was supposed to dump the current date. The month and day are correct but the year is off by about 1900 or so any ideas as to why
Calendar calendar=Calendar.getInstance();
Date validDate = new Date(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
complain(validDate.toString());
complain is a function I wrote to simply the dump the value of a string to the screen in an alert box
It shows this 3913-02-10
I need to get this fixed before I start doing comparisons so the quicker the better
OK I added some new code and not using the depracated Date any longer but now my month is of by 1 it shows 2013 1 10
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
complain(String.valueOf(year) + " " + String.valueOf(month) + " " + String.valueOf(day));
After further research I found that MONTH returns the correct value but I have to say this is VERY unintuitive I would think that it would coincide with normal understandings of the date format
This has January set to 0, February to 1, March to 2, etc. it is non intuitive.
Thanks to all
You are using a deprecated constructor that takes the year - 1900 as its first argument.
Depending on what you're gonna end up doing with the app, take this with a grain of salt:
Just subtract 1900 from the year and send that to your method or whatever you're doing.
Note: THIS IS A TERRIBLE PROGRAMMING PRACTICE and if this is anything other than self-education, FIND A BETTER WAY.

How do I set the date for a date picker?

I use DatePickerDialog.OnDateSetListener that's works fine.
I want to add date for 120 days in date picker.
What I mean is if I add 120 days, the date and month will be change automatically.
How to do it?
Something like this should do the trick:
Calendar cal = Calendar.getInstance();
cal.set(datepick.getYear(), datepick.getMonth() + 1, datepick.getDayOfMonth());
cal.add(Calendar.DATE, 120);
datepick.updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) - 1, cal.get(Calendar.DATE));
Make sure you create a date object with 120 days added (see this topic on how to do that) and use that to populate your datepicker, either on initialization or when changed. I'm not really sure what you are trying to achieve however the latter doesn't seem right usability wise. In that case I would create an extra textfield that represents the +120 days date.
Set Date Programmatically by using UpdateDate
datePickerDialog.UpdateDate(selectedDate ?? DateTime.Now);

-1469913 days left when calculating reoccurring events in Android

For reoccurring events, I want to show the number of days left until the next occurrence in my Android calendar application.
Example:
Today: 2012-06-12
Reoccurring event: 19th June
=> 13 days left
In order to achieve this, I save the first occurrence in an object of data type Calendar:
private Calendar cal;
...
cal = new GregorianCalendar();
cal.set(Calendar.YEAR, USER_INPUT_YEAR);
cal.set(Calendar.MONTH, USER_INPUT_MONTH);
...
To calculate the days left I use this function:
public int getDaysLeft() {
Date next = this.getNextOccurrence();
if (next == null) {
return -1;
}
else {
long differenceInMilliseconds = next.getTime()-System.currentTimeMillis();
double differenceInDays = (double) differenceInMilliseconds/DateUtils.DAY_IN_MILLIS;
return (int) Math.ceil(differenceInDays);
}
}
Which uses this function:
public Date getNextOccurrence() {
if (this.cal == null) {
return null;
}
else {
Calendar today = new GregorianCalendar();
Calendar next = new GregorianCalendar();
next.setTime(this.cal.getTime());
next.set(Calendar.YEAR, today.get(Calendar.YEAR));
if ((today.get(Calendar.MONTH) > this.cal.get(Calendar.MONTH)) || ((today.get(Calendar.MONTH) == this.cal.get(Calendar.MONTH)) && (today.get(Calendar.DAY_OF_MONTH) > this.cal.get(Calendar.DAY_OF_MONTH)))) {
next.add(Calendar.YEAR, 1);
}
return next.getTime();
}
}
By the way, to get the initial date, I expect to find a YYYY-MM-DD value and parse it like this:
(new SimpleDateFormat("yyyy-MM-dd")).parse(INPUT_DATE_STRING)
This works fine in most cases, but some users report that they see numbers such as -1469913 as "days left". How can this happen?
I thought the date (cal) might be not set or invalid, but then it would show -1 or something like this, as there are null checks in all parts, right?
-1469913 means something like -4027 years ago! As it is a reoccurring event, I thought the "days left" information should always be between 0 and 366. What could cause this code to produce such a number? Does this mean that getNextOccurrence() returns a data that is 4027 years in the past? I can't explain this behaviour.
I hope you can help me. Thank you so much in advance!
Edit: As it may be helpful: The wrong dates' year is always output as 1 when using DateFormat.getDateInstance().format(), e.g. Jan 3, 1. Nevertheless, the result of getDaysLeft() is something like 4k years.
Edit #2: I found out a date like 1--22199-1 is one that produces the output of "4k years left". Nevertheless, it is successfully parsed by (new SimpleDateFormat("yyyy-MM-dd")).parse(). Similarly, -1-1-1-91- is correctly parsed as Jan 1, 2.
Edit #3: It turned out that a date as simple as "0000-01-03" was causing all the trouble. When I output the time in milliseconds it says -62167222800000. When I then output it to a GMT string it says 0001-01-03 - strange, isn't it? And when I set the year to 1900 the time in millis is suddenly -122095040400000. Why?
Working with dates it can be really difficult to figure out those obscure errors before they happen to a user in the wild. In many cases, it can be worth your time to make a little unit test that throws a few tens of million dates in the machinery and see if any extreme answers pop up.
Also this might be worth reading. You wont realize how bad the java date-class are before you have tried something that is way better. :)
EDIT: If the users give a very high input value, then there can be a number overflow when you throw your result to an integer in getDaysLeft(). Just keep it as a long. Or even better: Only accept sensible input value, warn the user if they input the year 20120 or something like that :)
EDIT2: I was wrong in my last edit, .ceil() protects against number overflows. To be honest I have no longer any idea how this bug can happen.
EDIT3: Responding to your third edit: Remember, Date and Calendar uses Unix time. That means that the time represented by a zero is 1970. Everything before 1970 will be represented by a negative value.
EDIT4: Remember that javas calendar-classes sucks. This code snippet demonstrates that the error is in fact in the Calendar-class:
Calendar next = new GregorianCalendar();
long date1 = -62167222800000L;
long date2 = -62135600400000L;
next.setTimeInMillis(date1);
next.set(Calendar.YEAR, 2012);
System.out.println(next.getTimeInMillis());
next.setTimeInMillis(date2);
next.set(Calendar.YEAR, 2012);
System.out.println(next.getTimeInMillis());
Output:
-125629491600000
1325545200000
It will however be very hard to track down the exact bug that causes this. The reason all those bugs remains are because fixing them might break legacy systems all over the world. My guess is that the bug originates from the inability to give negative years. This, for example, will give the output "2013":
Calendar next = new GregorianCalendar();
next.set(Calendar.YEAR, -2012);
System.out.println(next.get(Calendar.YEAR));
I would simply recommend you to not allow such extreme values in your input. Decide on an acceptable span and give an error message if the value is outside of those boundaries. If you would like to handle all possible dates in some futher application, just use joda time. You wont regret it :)
You got negative values in days that might be because user have entered the date of next occurance which is any previous date.
I think you should calculate your daysLeft like this way,
String inputDateString = "19/06/2012";
Calendar calCurr = Calendar.getInstance();//current date
Calendar calNext = Calendar.getInstance();// for next date
calNext.setTime(new Date(inputDateString)); // or do set Day,Month,Year like in your Question
if(calNext.after(calCurr)) // if the next date is after current
{
long timeDiff = calNext.getTimeInMillis() - calCurr.getTimeInMillis(); // time of next year if today is 15 june and some one enter 16 june for next occurance
int daysLeft = (int) (timeDiff/DateUtils.DAY_IN_MILLIS); // Days Left
}
else
{
long timeDiff = calCurr.getTimeInMillis() - calNext.getTimeInMillis();
timeDiff = DateUtils.YEAR_IN_MILLIS - timeDiff; // time of next year if today is 15 june and some one enter 14 june for next occurance
int daysLeft = (int) (timeDiff/DateUtils.DAY_IN_MILLIS); // Days Left
}

Categories

Resources