This question already has answers here:
Get Last Friday of Month in Java
(16 answers)
Closed 4 years ago.
I have to fetch date of last Thursday of month of any year but the problem I'm facing is that for the month of dec'15 last thursday is 31-dec-2015 but I'm getting 24-dec-2015 for the following code:
Date getLastThursday(def month, def year ) {
Calendar cal = Calendar.getInstance();
cal.set( year, month,1 )
cal.add( Calendar.DAY_OF_MONTH, -(cal.get(Calendar.DAY_OF_WEEK )%7+2) );
return cal.getTime();
}
And also explain me how this line of code internally works?
cal.add(Calendar.DAY_OF_MONTH, -(cal.get(Calendar.DAY_OF_WEEK )%7+2))
If you use Java 8+, you can use a temporal adjuster (part of the Java Time API):
int month = 12;
int year = 2015;
LocalDate lastThursday = LocalDate.of(year, month, 1).with(lastInMonth(THURSDAY));
System.out.println("lastThursday = " + lastThursday); //prints 2015-12-31
Note: requires static imports
import static java.time.DayOfWeek.THURSDAY;
import static java.time.temporal.TemporalAdjusters.lastInMonth;
If you can't use the new API, I suspect the problem is in the modulus operation and this should work:
//month should be 0-based, i.e. use 11 for December
static Date getLastThursday(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(year, month + 1, 1);
cal.add(Calendar.DAY_OF_MONTH, -((cal.get(Calendar.DAY_OF_WEEK) + 2) % 7));
if (cal.get(Calendar.MONTH) != month) cal.add(Calendar.DAY_OF_MONTH, -7);
return cal.getTime();
}
The second if condition is there to make sure we have gone back one month.
Just put your modulus % outside:
cal.add( Calendar.DAY_OF_MONTH, -(cal.get(Calendar.DAY_OF_WEEK )+2)%7 );
if not, you get -8 => 24 december
and use month+1
Related
i try to get a previous date of custom date that selected by a user but i cant find a way to do that
this is the code
calendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange( #NonNull CalendarView view, int year, int month, int dayOfMonth ) {
finalDate = (dayOfMonth + 7) + "/" + (month - 3) + "/" + year;
try {
Date date = new SimpleDateFormat("dd/MM/yyyy").parse(finalDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
});
so if i select 30/2/2020 the result is : (37/-1/2020)
java.time and ThreeTenABP
Consider using java.time, the modern Java date and time API, for your date work. Not least when you need to math on dates. I frankly find it much better suited than the old and outdated Calendar class, not to mention Date and SimpleDateFormat.
int year = 2020;
int month = Calendar.MARCH; // For demonstration only, don’t use Calendar in your code
int dayOfMonth = 30;
LocalDate selectedDate = LocalDate.of(year, month + 1, dayOfMonth);
LocalDate finalDate = selectedDate.minusMonths(3).plusDays(7);
System.out.println(finalDate);
Output:
2020-01-06
I believe that your Android date picker numbers months from 0 for January through 11 for December, so we need to add 1 to convert to the natural way that humans and LocalDate number months. When we start out from 30th March, we subtract 3 months and get 30th December, then add 7 days and get 6th January. We might also have done the math in the opposite order:
LocalDate finalDate = selectedDate.plusDays(7).minusMonths(3);
In this case it gave the same result, but since months have unequal lengths, it won’t always.
Isn't it because you are adding 7 to your day count and subtracting 3 from your month count? Try removing that and it should work better.
Here in the UK, the tax year runs from 6 April to 5 April each year. I want to get the start date of the current tax year (as a LocalDate), so for example if today is 3 April 2020, then return 6 April 2019, and if today is 8 April 2020, then return 6 April 2020.
I can calculate it using some logic like the following:
date = a new LocalDate of 6 April with today's year
if (the date is after today) {
return date minus 1 year
} else {
return date
}
But is there some method I can use that is less complex and uses a more succinct, perhaps functional style?
There are a few different approaches, but it's easy enough to implement the logic you've already specified in a pretty functional style:
private static final MonthDay FINANCIAL_START = MonthDay.of(4, 6);
private static LocalDate getStartOfFinancialYear(LocalDate date) {
// Try "the same year as the date we've been given"
LocalDate candidate = date.with(FINANCIAL_START);
// If we haven't reached that yet, subtract a year. Otherwise, use it.
return candidate.isAfter(date) ? candidate.minusYears(1) : candidate;
}
That's pretty concise and simple. Note that it doesn't use the current date - it accepts a date instead. That makes it much easier to test. It's easy enough to call this and provide the current date, of course.
using java.util.Calendar, you can get financial year's START and END date in which your given date lies.
In India financial year starts from from 1 April and ends on 31st March,
for financial year 2020-21 , dates will be 1 April 2020
public static Date getFirstDateOfFinancialYear(Date dateToCheck) {
int year = getYear(dateToCheck);
Calendar cal = Calendar.getInstance();
cal.set(year, 3, 1); // 1 April of Year
Date firstAprilOfYear = cal.getTime();
if (dateToCheck.after(firstAprilOfYear)) {
return firstAprilOfYear;
} else {
cal.set(year - 1, 3, 1);
return cal.getTime();
}
}
In your case set cal.set(year, 0, 1); // 1 Jan of Year
public static Date getLastDateOfFinancialYear(Date dateToCheck) {
int year = getYear(dateToCheck);
Calendar cal = Calendar.getInstance();
cal.set(year, 2, 31); // 31 March of Year
Date thirtyFirstOfYear = cal.getTime();
if (dateToCheck.after(thirtyFirstOfYear)) {
cal.set(year + 1, 2, 31);
return cal.getTime();
} else {
return thirtyFirstOfYear;
}
}
In your case set cal.set(year, 11, 31); // 31 Dec of Year
This question already has answers here:
Why does Java's Date.getYear() return 111 instead of 2011?
(6 answers)
Closed 5 years ago.
I'm trying to get year from the Date, and with Calendar.get(Calendar.YEAR) i get year 3917 instead of 2017 ? But when i try to check output with date.getYear() it returns the correct year.
Date date = new Date(year, month, day);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
Log.d(TAG, "onClick: year "+date.getYear());
Log.d(TAG, "onClick: year "+calendar.get(Calendar.YEAR));
Output:
onClick: year 2017
onClick: year 3917
Date class displays the correct year but Calendar displays wrong year
Here's the Javadoc of Date class, this is what it says about the constructor that you are using:
Deprecated. As of JDK version 1.1, replaced by Calendar.set(year +
1900, month, date) or GregorianCalendar(year + 1900, month, date).
Allocates a Date object and initializes it so that it represents
midnight, local time, at the beginning of the day specified by the
year, month, and date arguments.
Also, here's the explanation for parameters:
Parameters:
year - the year minus 1900.
month - the month between
0-11.
date - the day of the month between 1-31.
As it adds 1900 to the value you pass, the resultant year you are getting is 3917.
As said in other answers, Date year is a number of year from 1900 (more information in the complete answer of Darshan Mehta).
But there is a simpler solution using LocalDate.of to create a date to year, month, day and using LocalDate.getYear to get the specific year :
java.time.LocalDate date = java.time.LocalDate.of(2017, 9, 1);
System.out.println(date.getYear());
2017
java.util.Date is outdated (and all the method you used are deprecated), you should look to the java.time api that is more readable and functional
Method of Date:
public Date(int year, int month, int day) {
GregorianCalendar cal = new GregorianCalendar(false);
cal.set(1900 + year, month, day);
milliseconds = cal.getTimeInMillis();
}
As you can see, 1900 are added to your calendar date. Which results in 3917
public static void main(String[] args) {
int week = 1;
int year = 2010;
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.WEEK_OF_YEAR, week);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();
System.out.println(date);
}
I'm looking for the exact start and end DATE's as per our desktop calendars if I give week, year as input.
But the above code is giving the output as 27th Jan, 2009, Sunday.
I know it's because the default first day of a week is SUNDAY as per US, but I need as per the desktop calendar 1st Jan, 2010, Friday as starting date of the week
My Requirement :
If my input is :
Week as '1',
Month as '5',
Year as '2015'
I need :
1st May, 2015 --> as first day of the week
2nd May, 2015 --> as last day of the week
If my input is :
Week as '1',
Month as '6',
Year as '2015'
I need :
1st June, 2015 --> as first day of the week
6th June, 2015 --> as last day of the week
Can anyone help me?
Instead of using CALENDAR.Week, use Calendar.DAY_OF_YEAR. I just tested it and it works for me:
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, 2010);
calendar.set(Calendar.DAY_OF_YEAR, 1);
System.out.println(calendar.getTime());
calendar.set(Calendar.DAY_OF_YEAR, 7);
System.out.println(calendar.getTime());
}
If you want this to work for an arbitrary week, just do some math to figure out which day of the year you want.
Edit: If you want to input a month as well, you can use Calendar.DAY_OF_MONTH.
I wrote a Swing calendar widget. One method in that widget calculates the first day of the week when a week starts on a user selected day, like Friday.
startOfWeek is an int that takes a Calendar constant, like Calendar.FRIDAY.
DAYS_IN_WEEK is an int constant with the value 7.
/**
* This method gets the date of the first day of the calendar week. It could
* be the first day of the month, but more likely, it's a day in the
* previous month.
*
* #param calendar
* - Working <code>Calendar</code> instance that this method can
* manipulate to set the first day of the calendar week.
*/
private void getFirstDate(Calendar calendar) {
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) % DAYS_IN_WEEK;
int amount = 0;
for (int i = 0; i < DAYS_IN_WEEK; i++) {
int j = (i + startOfWeek) % DAYS_IN_WEEK;
if (j == dayOfWeek) {
break;
}
amount--;
}
calendar.add(Calendar.DAY_OF_MONTH, amount);
}
The rest of the code can be seen in my article, Swing JCalendar Component.
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):