I have a CalendarView in my app, when the user selects a date by touching that date in the monthview, the correct date is selected (verified by adding debug statements in the code), but the week before is highlighted, so it looks as if the wrong date is selected.
I have found a work-around: if I set 'firstDayInWeek' to 1 the problem is solved, but by default the firstDayInweek is 2 (monday), and then this problem occurs.
Thank you very much!
Samsung S4 with API 21
I have had the same issue as you, using a Samsung S5 running API 21.
There are two workarounds that I have found, none of them is a good experience for our users :(
Force first day of the week to Sunday
calendarView.setFirstDayOfTheWeek(Calendar.SUNDAY);
Set a minimum and a maximum date for the calendar (be careful because not all of the dates work here). I was able to make it work properly setting a minimum date 2 months before the current date and maximum date 2 years after the current date. You can play with these values and find a good compromise between the limits and your user experience.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 2);
calendarView.setMinDate(calendar.getTimeInMillis());
calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 2);
calendarView.setMaxDate(calendar.getTimeInMillis());
Unfortunately, this is the only way I could fix this issue, I hope it is useful for you.
Related
How to set first day of week to monday or saturday ?
I can't find method or variable to change it. Like picture example below, first day of week is monday. Thanks in advance.
link github DateRangePicker https://github.com/savvisingh/DateRangePicker
Thanks for the answer. I finally figure it out. You need to initialize Locale and Timezone to change first day of week. Not calendar that you have to change. Don't need to break the library code too.
new CalendarPickerView.init(date1, date1, TimeZone.getDefault(), Locale.UK, new SimpleDateFormat("MMMM, YYYY", Locale.getDefault())) //
.inMode(CalendarPickerView.SelectionMode.MULTIPLE)
.withSelectedDates(listDate);
The first day of week is determined by your locale.
Set it to something like English (UK) or German and you will have Monday as first day of week.
Then if it dosen't work you can change by code, like :
datePickerDialog.setFirstDayOfWeek(int weekStart);
If you want monday weekStart = 2
I hope it will help you!
As per you using the DateRangePicker library :
For Example:
Use this code in your project.
// create a calendar
Calendar cal = Calendar.getInstance();
// set first day of the week as something else
cal.setFirstDayOfWeek(Calendar.WEDNESDAY);
or it will not run then required for you to change in library code with create method and put above code then used it in your project.
I have looked at that repository. The library creates days from 0 to 7 in a loop and gets days. See this.
The calendar here in use is created in init method in CalendarPickerView. Look at CalendarPickerView.
today = Calendar.getInstance(timeZone, locale);
I think if you change first day of week of calendar or default locale/timezone, you can do what you want.
I'm stuck with one interesting problem.
I have a Calendar object with European style(? don't know how to call it right) i.e. week starts on Monday and ends on Sunday.
My issue appears when I change device language to English(U.S.). Calendar object changes its style to American i.e. week starts on Sunday and ends on Saturday.
Unfortunately I need week to start on Monday and end on Sunday but I can't understand how to do that.
I tried
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar = Calendar.getInstance(Locale.FRANCE);
but it doesn't work.
Thanks in advance!
LocalDate today=LocalDate.now();
And the event date is:
eventDate=LocalDate.of(year, monthOfYear,dayOfMonth); (from the date picker dialog)
I'm trying to calculate the days difference between them... The shortest thing I have found is this:
int DaysDifference = Period.between(eventToDisplay.getEventDate(),today).getDays();
While the first object is "today", and the second one is "eventToDisplay.getEventDate()." It didn't work for me, it showed the wrong number of days.
I have also tried to do it like this:
eventToDisplay.getEventDate().compareTo(today)
Also didn't work...
I have also tried to do it without joda-time, because I had troubles with it, because of what I'm trying to do with date and time...
The other things I have found are long and complicated, and I thought maybe there is a better way, without the joda-time.
EDIT:
I have just tried this:
Calendar now = Calendar.getInstance();
Calendar chosenDate=Calendar.getInstance();
chosenDate.set(eventToDisplay.getEventDate().getYear(),eventToDisplay.getEventDate().getMonth().getValue(),eventToDisplay.getEventDate().getDayOfMonth());
long def= chosenDate.getTimeInMillis() - now.getTimeInMillis();
long DaysDifference =TimeUnit.MILLISECONDS.toDays(def);
Didn't work for me
EDIT:
This has worked for me:
LocalDate today=LocalDate.now();
Calendar now = Calendar.getInstance();
now.set(today.getYear(),today.getMonthValue(),today.getDayOfMonth());
Calendar chosenDate=Calendar.getInstance();
chosenDate.set(eventToDisplay.getEventDate().getYear(),eventToDisplay.getEventDate().getMonthValue(),eventToDisplay.getEventDate().getDayOfMonth());
long def= chosenDate.getTimeInMillis() - now.getTimeInMillis();
long daysDifference =TimeUnit.MILLISECONDS.toDays(def);
you can use something like this:
Calendar now = Calendar.getInstance();
Calendar end=Calendar.getInstance();
end.set(<year>, <month>, <day>);
long def= end.getTimeInMillis() - now.getTimeInMillis();
long days =TimeUnit.MILLISECONDS.toDays(def);
java.time
Since you can use LocalDate from java.time, the modern Java date and time API, I warmly recommend that you stick to java.time. Calculating the difference is simple and straightforward when you know how:
LocalDate today = LocalDate.now(ZoneId.systemDefault());
LocalDate eventDate = LocalDate.of(2021, 5, 5);
long differenceDays = ChronoUnit.DAYS.between(today, eventDate);
System.out.println("Difference is " + differenceDays + " days.");
Output when I ran today (APril 18 in my tme zone):
Difference is 17 days.
If your date picker uses 0-based months (some date pickers insanely use 0 for January through 11 for December), remember to add 1 to the month number before passing it to LocalDate.
What went wrong in all your attempts?
int DaysDifference = Period.between(eventToDisplay.getEventDate(),today).getDays();
The Period class represents a period of years, months and days. Since months have different lengths, a Period does not correspond to any exact number of days, so it’s not the right class to use here. You tried to use its getDays method, which gives you the days component of the period, not the months or the years. So if the two days are less than a month apart, you will get the correct result, otherwise not. If for example the two dates are 1 month 3 days apart, you will only get the 3 days.
The Calendar class used in more than one of your attempts is poorly designed and long outdated. Counting days correctly with it would be truly cumbersome, so no wonder that your attempts gave the wrong results.
Both of your attempts are wrong for at least two reasons:
A Calendar has a date and a time of day. So by finding the difference in milliseconds and dividing by the number of milliseconds that you think are in a day, you will get different results depending on the time of day that happens to be in each of your Calendar objects. Your code calls Calendar.getInstance() twice. In an extreme situation your code may run across midnight so the time in the first Calendar will be close to 23:59:59 and in the second close to 00:00, which will almost certainly give you an error of 1 day.
A day is not always 24 hours. Summer time (DST) is the most frequent but not the only reason why a date is sometimes 23 hours, 25 hours or some other length. If for example you try to count days across the spring forward where a day is only 23 hours or 23 hours 30 minutes, your code will count 1 day too few.
Furthermore this line from the snippet that you say that works is definitely wrong:
now.set(today.getYear(),today.getMonthValue(),today.getDayOfMonth());
You are using the 1-based month number from LocalDate, for example 4 for April, as a 0-based month number in Calendar, for example 4 would mean May. So your Calendar is off by 1 month. Since I haven’t got your complete code, is may in some cases balance out by another error that causes the other Calendar to be 1 month off too, I cannot know. Since months have different lengths, you will still get an error of up to 3 days sometimes.
This question already has an answer here:
android timezone difference is 1 hour less then expected
(1 answer)
Closed 9 years ago.
I need an offset for "Europe/Russia" to UTC.. in hours. here is my code:
Calendar mCalendar = new GregorianCalendar();
mCalendar.setTimeZone( TimeZone.getTimeZone("Europe/Moscow"));
TimeZone mTimeZone = mCalendar.getTimeZone();
int remote_offset = mTimeZone.getRawOffset()/1000/60/60;
For UTC it should be -4 hours. BUT! some user got 3 hours difference!!
I think, the problem is, Russia doesn't use winter time. And some devices now that, but some not.. how could I implement allway to get "-4" hours?
Regards
First, Russia isn't UTC-4.
The problem has to do with Russia not having daylight saving time. But your issue is probably only happening with android 2.x device and less. The daylight saving time was removed before 4.x as far as I remember (if it's a user input). On the other hand, if you receive a date that was created by the device without user input, you don't have to convert it as it's already as UTC.
But as I said, Russia isn't -4. Russia/Moscow will be +4 hours. But Russia is larger than Moscow really!
Look here: http://en.wikipedia.org/wiki/Time_in_Russia
UTC+03:00 MSK−1: Kaliningrad Time Europe/Kaliningrad
UTC+04:00 MSK: Moscow Time Europe/Moscow, Europe/Volgograd, Europe/Samara
UTC+06:00 MSK+2: Yekaterinburg Time Asia/Yekaterinburg
UTC+07:00 MSK+3: Omsk Time Asia/Omsk, Asia/Novosibirsk, Asia/Novokuznetsk
UTC+08:00 MSK+4: Krasnoyarsk Time Asia/Krasnoyarsk
UTC+09:00 MSK+5: Irkutsk Time Asia/Irkutsk
UTC+10:00 MSK+6: Yakutsk Time Asia/Yakutsk
UTC+11:00 MSK+7: Vladivostok Time Asia/Vladivostok, Asia/Sakhalin
UTC+12:00 MSK+8: Magadan Time Asia/Magadan, Asia/Kamchatka, Asia/Anadyr
So what you'll have to do is to check if we're in winter and that the TimeZone is one of those. If the timezone is one of those, you can add one more hour when you want to show. And remove 1 hour when you want to convert to UTC.
I don't believe it's possible to update the TimeZone on the android phones and that also means that it's not exactly possible to do that unless you find an alternative library for Dates that has timezones built-in and which are updated.
You could subclass the DateObject with the functions that you use to behave just like the old date object, all you'll have to do is to make sure it behaves differently on android2.x and not on android 4.x+.
Also check this: http://www.joda.org/joda-time/
I checked there and I guess it could be usable and less hacky than my suggestion above. The TimeZones are up to date so it could just work for every phone since it shouldn't use the internal timezones. On the other hand, if you have functions that require the Date, it might get tricky.
My suggestion is make sure you use UTC everywhere and use JodaTime to format the date with timezones and to do "datetime" operations. If you make sure that your Java Date never contain a TimeZone other than UTC. It should work.
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);