Automatic correction of Java Calendar day of month? - java

I want to learn that is there any easiest way to correct the values of day when setting it. I mean:
int birthDay = 30;
int birthMonth = 1;
int birthYear = 1980;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, birthDay);
cal.set(Calendar.MONTH, birthMonth);
cal.set(Calendar.YEAR, birthYear);
February doesn't have the day of 30. On the other hand it has a special condition, 1980 is a year that February is 29 days. So I have to get the corrected value as "1980-February-29". It should take the maximum day of that month if I exceed the range of month. How can I do it at simplest way and if I can find solution that doesn't need to write any extra code instead of using the methods of Calendar class it will be perfect.
EDIT: I changed cal.set(Calendar.MONTH, birthMonth-1); to cal.set(Calendar.MONTH, birthMonth); sorry for it.

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, birthYear);
cal.set(Calendar.MONTH, birthMonth);
cal.set(Calendar.DAY_OF_MONTH, Math.min(birthDay, cal.getActualMaximum(Calendar.DAY_OF_MONTH)));

Use calendar.getActualMaximum(Calendar.DAY_OF_MONTH) to find the maximum day of the month

No, currently it's the only way.
Of course, you might want to parse a date from a String using a java.text.DateFormat object (typically a SimpleDateFormat). This is the most close to a one-liner you can get if your input is a String.

Related

Android , Calendar.getInstance() not giving the correct month

I am trying to write code to find the Day difference between tow date but Calendar.getInstance() keep getting the date for previous month instead of current month
for example :Current 17/7/2014 it get 17/6/2014
my code :
TextView textview=(TextView) findViewById (R.id.textView1);
Calendar cal = Calendar.getInstance();
Calendar startDate=Calendar.getInstance();
startDate.set(Calendar.DAY_OF_MONTH, 1);
startDate.set(Calendar.MONTH,1);
startDate.set(Calendar.YEAR, 2013);
long diff=(((cal.getTimeInMillis()-startDate.getTimeInMillis())/(1000*60*60*24))+1);
String sdiff=String.valueOf(diff);
String stt=cal.get(Calendar.YEAR) +"_"+cal.get(Calendar.MONTH)+"_"+cal.get(Calendar.DAY_OF_MONTH);
textview.setText(stt);
Months start at 0, not at 1, but you really don't have to worry about this if you don't use magic numbers when getting or setting month but instead use the constants. So not this:
startDate.set(Calendar.MONTH,1); // this is February!
but rather
startDate.set(Calendar.MONTH, Calendar.JANUARY);
Months in Java's Calendar start with 0 for January, so July is 6, not 7.
Calendar.MONTH javadocs:
The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0
Add 1 to the result of get.
(cal.get(Calendar.MONTH) + 1)
This also affects your set call. You can either subtract 1 when passing a month number going in, or you can use a Calendar constant, e.g. Calendar.JANUARY.
You can also use a SimpleDateFormat to convert it to your specific format, without having to worry about this quirk.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd");
String stt = sdf.format(cal.getTime());

How to get all the dates in a month using calender class?

Here I want to display dates like
2013-01-01,
2013-01-02,
2013-01-03,
.
.
...etc
I can get total days in a month
private int getDaysInMonth(int month, int year) {
Calendar cal = Calendar.getInstance(); // or pick another time zone if necessary
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DAY_OF_MONTH, 1); // 1st day of month
cal.set(Calendar.YEAR, year);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
Date startDate = cal.getTime();
int nextMonth = (month == Calendar.DECEMBER) ? Calendar.JANUARY : month + 1;
cal.set(Calendar.MONTH, nextMonth);
if (month == Calendar.DECEMBER) {
cal.set(Calendar.YEAR, year + 1);
}
Date endDate = cal.getTime();
// get the number of days by measuring the time between the first of this
// month, and the first of next month
return (int)((endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000));
}
Does anyone have an idea to help me?
If you only want to get the max number of days in a month you can do the following.
// Set day to one, add 1 month and subtract a day
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, 1);
cal.add(Calendar.DAY_OF_MONTH, -1);
return cal.get(Calendar.DAY_OF_MONTH);
If you actually want to print every day then you can just set the day of month to 1 and keep adding a day in a loop until the month changes.
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
int myMonth=cal.get(Calendar.MONTH);
while (myMonth==cal.get(Calendar.MONTH)) {
System.out.print(cal.getTime());
cal.add(Calendar.DAY_OF_MONTH, 1);
}
Modern answer: Don’t use Calendar. Use java.time, the modern Java date and time API.
YearMonth ym = YearMonth.of(2013, Month.JANUARY);
LocalDate firstOfMonth = ym.atDay(1);
LocalDate firstOfFollowingMonth = ym.plusMonths(1).atDay(1);
firstOfMonth.datesUntil(firstOfFollowingMonth).forEach(System.out::println);
Output (abbreviated):
2013-01-01
2013-01-02
2013-01-03
…
2013-01-30
2013-01-31
datesUntil gives us a stream of dates until the specified end date exclusive, so when we give it the 1st of the following month, we get exactly all the dates of the month in question. In this example case up to and including January 31.
Link: Oracle tutorial: Date Time explaining how to use java.time.
This will give you all days of a month.
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
System.out.print(df.format(cal.getTime()));
for (int i = 1; i < maxDay; i++) {
cal.set(Calendar.DAY_OF_MONTH, i + 1);
System.out.print(", " + df.format(cal.getTime()));
}
The first date is printed outside of loop for comma separated output.
A couple of comments...
Firstly, "... Calendar objects are particularly expensive to create." (J. Bloch, Effective Java, 2nd Ed.). If this is a method that you are going to be calling frequently, consider that you do not need to create a new Calendar object every time you call it.
Consider using a Calendar object held in a private static field that is initialized with a static initializer block. This presumes a single-threaded solution and would require synchronization in a concurrent environment. Otherwise, it really ought to be possible to reuse the same Calendar for your calculations.
Secondly, while you can find that greatest value for the DAY_OF_MONTH by iterating over the possible valid values, I think you can let the API do it for you. Consider using the getMaximum(DAY_OF_MONTH) or getGreatestMaximum(DAY_OF_MONTH) methods of the Calendar class.
Write a common method like that if you are using kotlin-
fun getAllDateOfMonth(year: Int, month: Month): List<LocalDate> {
val yearMonth= YearMonth.of(year, month)
val firstDayOfTheMonth = yearMonth.atDay(1)
val datesOfThisMonth = mutableListOf<LocalDate>()
for (daysNo in 0 until yearMonth.lengthOfMonth()){
datesOfThisMonth.add(firstDayOfTheMonth.plusDays(daysNo.toLong()))
}
return datesOfThisMonth
}
And call it like that -
getAllDateOfMonth(2021,Month.MAY):

Android Calendar: Changing the start day of week

i have a little problem, i'm developing an application, and i need to change the start day of the week from monday to another one (thursday, of saturday). is this possible in android,
i need to calculate the start to week and its end knowing the date. (the week starts ano thursday as example)
Note: i'm just a beginner in android development.
here is my code
SimpleDateFormat dateformate = new SimpleDateFormat("dd/MM");
// get today and clear time of day
Calendar cal = Calendar.getInstance();
// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
cal.add(Calendar.DAY_OF_YEAR, 7*(WeekIndex-1));
result = dateformate.format(cal.getTime());
cal.add(Calendar.DAY_OF_YEAR, 6 );
result=result+" - " + dateformate.format(cal.getTime());
using the above code im getting the result but with monday as the star of week.
Note: i can't add day to the result because week index changes with the changing of it's start
Calendar days have values 1-7 for days Sunday-Saturday. getFirstDayOfWeek returns one of this values (usually of Monday or Sunday) depending on used Locale. Calendar.getInstance uses default Locale depening on phone's settings, which in your case has Monday as first day of the week.
One solution would be to use other Locale:
Calendar.getInstance(Locale.US).getFirstDayOfWeek()
would return 1, which is value of Calendar.SUNDAY
Other solution would be to use chosen day of week value like
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
Problem is, Calendar is using its inner first day of the week value in set as well. Example:
Calendar mondayFirst = Calendar.getInstance(Locale.GERMANY); //Locale that has Monday as first day of week
mondayFirst.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
log(DateUtils.formatDateTime(context, mondayFirst.getTimeInMillis(), 0));
//prints "May 19" when runned on May 13
Calendar sundayFirst = Calendar.getInstance(Locale.US); //Locale that has Sunday as first day of week
sundayFirst.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
log(DateUtils.formatDateTime(context, sundayFirst.getTimeInMillis(), 0));
//prints "May 12" when runned on May 13
If you don't want to use Locale or you need other day as the first day of the week, it may be best to calculate start of the week on your own.
GregorianCalendar cal = new GregorianCalendar(yy, currentMonth, 0);
changing the value 0 - starts day from monday
changing the value 1 - starts day from sunday
and so on..
hope this helps and works :)
public int getWeekdayOfMonth(int year, int month){
Calendar cal = Calendar.getInstance();
cal.set(year, month-1, 1);
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)-1;
return dayOfWeek;
}
weekday = getWeekdayOfMonth();
int day = (weekday - firstweek) < 0 ? (7 - (firstweek - weekday)) : (weekday - firstweek);
"firstweek" means what the start day of you want
then you can calculate the first day you should show.If you have simple method,please tell us. thks
Problem in my case was using Calendar instance returned by MaterialDialog DatePicker, which although having the same Locale as my Calendar.getInstance(Locale...), was having different Calendar.firstDayOfWeek. If you're experiencing the same issue, my workaround was to create new instance of Calendar with my Locale and just changing the property time to the one returned by the DatePicker as following:
val correctCal = Calendar.getInstance(Locale...)?.apply {
time = datePickerCal.time
}
This should return proper Calendar.firstDayOfWeek based on your Locale.

Android get difference in milliseconds between two dates

I have Integer fields:
currentYear,currentMonth,currentDay,currentHour,currentMinute and nextYear,nextMonth,nextDay,nextHour,nextMinute.
How I can get difference between those two spots in time in milliseconds.
I found a way using Date() object, but those functions seems to be depricated, so it's little risky.
Any other way?
Use GregorianCalendar to create the date, and take the diff as you otherwise would.
GregorianCalendar currentDay=new GregorianCalendar (currentYear,currentMonth,currentDay,currentHour,currentMinute,0);
GregorianCalendar nextDay=new GregorianCalendar (nextYear,nextMonth,nextDay,nextHour,nextMinute,0);
diff_in_ms=nextDay. getTimeInMillis()-currentDay. getTimeInMillis();
Create a Calendar object for currenDay and nextDay, turn them into longs, then subtract. For example:
Calendar currentDate = Calendar.getInstance();
Calendar.set(Calendar.MONTH, currentMonth - 1); // January is 0, Feb is 1, etc.
Calendar.set(Calendar.DATE, currentDay);
// set the year, hour, minute, second, and millisecond
long currentDateInMillis = currentDate.getTimeInMillis();
Calendar nextDate = Calendar.getInstance();
// set the month, date, year, hour, minute, second, and millisecond
long nextDateInMillis = nextDate.getTimeInMillis();
return nextDateInMillis - currentDateInMillis; // this is what you want
If you don't like the confusion around the Calendar class, you can check out the Joda time library.

Calendar returning the wrong time

The time displayed is way ahead of what I expected. I'm parsing a date string and turning it into milliseconds.
year = Integer.parseInt(m1.group(1));
mo = Integer.parseInt(m1.group(2));
day = Integer.parseInt(m1.group(3));
hr = Integer.parseInt(m1.group(4));
min = Integer.parseInt(m1.group(5));
sec = Integer.parseInt(m1.group(6));
and here I set the Calendar
Calendar cal = Calendar.getInstance();
cal.set(year, mo, day, hr, min, sec);
time = cal.getTimeInMillis();
If you check out the calendar documentation here, then visit here, you'll see that January is month 0. You'll want to change your code to mo = Integer.parseInt(m1.group(2))-1;
You should probably use DateFormatter to parse the date string (rather than rolling your own).
Other than that, make sure that you have the proper time zone and understand that month number one is February (not January).

Categories