Get third friday of a month - java

I develop a local calendar for my application. but there is an issue with monthly repeat event (day of week).
When i create an event starting on 16-9-2016(16 SEP 2016 FRIDAY) and repeating Third Friday of each month. but next month it create on second
Friday 14-10-2016 (This is the issue). next month it will be on third Friday.
my code is
public Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(timeZone);
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
calendar.set(Calendar.WEEK_OF_MONTH, week);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
return calendar.getTime();
}
I know the issue. but i don`t know how to fix it.. is there any way to fix it ?

You code seems to be working completely fine, there is nothing that is going wrong from what I can see, it may be that your parameters are wrong.
It is important to note that MONTH and DAY are 0-based so, 0 = January and 0 = Sunday so your parameters for getting the third friday should look like the following:
nthWeekdayOfMonth(6, 9, 2016, 3, TimeZone.getTimeZone("Europe/London"));
Which returns the following output:
Fri Oct 21 11:06:33 BST 2016
To break it down:
Day of week is 6, because Sunday = 0.
Month is 9 - i.e. October
Year is normal - 2016
Week is NOT 0-based so 3rd week will be index 3
TimeZone as normal
Please see the Calendar documentation for reference.
EDIT
So for some reason, it works on my machine but it doesn't on others; I don't know what the issue could be with that but using DAY_OF_WEEK_IN_MONTH seems to be a better option for this:
public static Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(timeZone);
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
//calendar.set(Calendar.WEEK_OF_MONTH, week);
calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, week);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
return calendar.getTime();
}
I usually use GregorianCalendar but Calendar should work just fine.
This should (hopefully) work for the most part, I've tested it on other machines and ideone.

I could propose next decision:
public Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(timeZone);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, 1);
// add +1 to week if first weekday of mounth > dayOfWeek
int localWeek = week;
if (calendar.get(calendar.DAY_OF_WEEK) > dayOfWeek) {
localWeek++;
}
calendar.set(Calendar.WEEK_OF_MONTH, localWeek);
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
return calendar.getTime();
}
for:
System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.SEPTEMBER, 2016, 3, TimeZone.getTimeZone("Europe/London")));
System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.OCTOBER, 2016, 3, TimeZone.getTimeZone("Europe/London")));
System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.NOVEMBER, 2016, 3, TimeZone.getTimeZone("Europe/London")));
it returns:
Fri Sep 16 19:41:23 YEKT 2016
Fri Oct 21 19:41:23 YEKT 2016
Fri Nov 18 20:41:23 YEKT 2016

Java 8
LocalDate thirdFriday = java.time.LocalDate.now()
.with(TemporalAdjusters.firstDayOfMonth())
.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY))
.plusDays(14)

java.time
java.time, the modern Java date and time API, has a built-in adjuster for that:
public LocalDate nthWeekdayOfMonth(DayOfWeek dayOfWeek, Month month, int year, int week) {
return LocalDate.of(year, month, 15)
.with(TemporalAdjusters.dayOfWeekInMonth(week, dayOfWeek));
}
Try it out:
System.out.println(nthWeekdayOfMonth(DayOfWeek.FRIDAY, Month.OCTOBER, 2016, 3));
Output:
2016-10-21
Please also note that the arguments that I pass to the method are much more telling.
Link: Oracle tutorial: Date Time explaining how to use java.time.

This is a functioning Java 8 implementation. The example from KayV did not work for September 2017, but it helped me to head in the right direction.
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OptionExpirationDates {
public static void main(String[] args) {
LocalDate startDate = LocalDate.of(2017, Month.FEBRUARY, 15);
List<LocalDate> optionExDates = optionExpirationDates(startDate, 20);
for (LocalDate temp : optionExDates) {
System.out.println(temp);
}
}
public static List<LocalDate> optionExpirationDates(LocalDate startDate, int limit) {
return Stream.iterate(startDate, date -> date.plusDays(1))
.map(LocalDate -> LocalDate.with(TemporalAdjusters.firstDayOfMonth()).minusDays(1)
.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)).plusWeeks(2))
.distinct()
.limit(limit)
.collect(Collectors.toList());
}
}
Perhaps we should also mention that this code is to calculate an option expiration date, so that the search engine can pick it up.

Java 8 way of doing this is as follows:
LocalDate thirdFriday = LocalDate
.now()
.with(lastDayOfMonth())
.with(previous(DayOfWeek.FRIDAY)).minusDays(7);

To take a different approach. If the first day of the month is a Saturday, then the third Friday is the 21st of that month. Extend this for the seven possible days:
Saturday 1st -> Friday 21st.
Sunday 1st -> Friday 20th
Monday 1st -> Friday 19th
Tuesday 1st -> Friday 18th
Wednesday 1st -> Friday 17th
Thursday 1st -> Friday 16th
Friday 1st -> Friday 15th
You just need to check what day of the week the first of the month is.

Below function can be used to calculate third friday of month using joda time. The function is verbose for sake of clarity on logic.
public static DateTime thirdFridayOfMonth(int year, int month) {
DateTime firstDayOfMonth = new DateTime(year, month, 1, 0, 0);
MutableDateTime mFirstDayOfMonth = new MutableDateTime(firstDayOfMonth);
//Now calculate days to 1st friday from 1st day of month
int daysToFirstFridayOfMonth = mFirstDayOfMonth.dayOfWeek().get() <= 5 ? (5 - mFirstDayofMonth.dayOfWeek().get()) : (7 - mFirstDayofMonth.dayOfWeek().get() + 5);
//move to first 1st friday of month
mFirstDayOfMonth.addDays(daysToFirstFridayOfMonth);
//move to 3rd friday of month
mFirstDayOfMonth.addWeeks(2);
return mFirstDayOfMonth.toDateTime();
}

with Java LocalDateTime
LocalDateTime firstDayOfMonth = LocalDateTime.of(year, Month.of(month), 1, 0, 0);
// Returns 1-7 (NOT 0-6)
int firstDayValue = firstDayOfMonth.getDayOfWeek().getValue();
int thirdFriday = 20 + firstDayValue / 6 * 7 - firstDayValue;
return LocalDateTime.of(year, Month.of(month), thirdFriday, 0, 0);

Related

How to select sunday before first monday of the passed month

I want to select Sunday before first Monday of the passed month.
That Sunday may be in the same month or the previous month but I want date of Sunday. I tried below logic for getting Sunday, it works for the current month but if I try passing some another month like Nov-2017 then again I have to change MONDAY-2 to MONDAY-3. So this is not the correct way. So how can I achieve this ?
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
c.set(Calendar.DAY_OF_MONTH, Calendar.MONDAY - 2);
System.out.println("Date " + c.getTime());
I want to pass date to the code. So how can i do it ? like if I have date saved in variable then according to the input provided by that variable it should calculate the logic and provide the output
#Test
public void testDate() throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
Date d = fmt.parse("01-Nov-2017");
System.out.println(d);
Calendar c = Calendar.getInstance();
c.setTime(d);
getSundayBefore1thMondayOfMonth(c);
}
public void getSundayBefore1thMondayOfMonth(Calendar c) {
c.set(Calendar.DAY_OF_MONTH, 1);
int wd = c.get(Calendar.DAY_OF_WEEK);
if (wd > Calendar.MONDAY ) {
c.add(Calendar.DAY_OF_MONTH, 7);
}
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println(c.getTime());
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(c.getTime());
}
Wed Nov 01 00:00:00 CST 2017
Mon Nov 06 00:00:00 CST 2017
Sun Nov 05 00:00:00 CST 2017
If you are using Java 8, Then you can use java.time library and you can just use :
LocalDate firstMondayOfMonth = LocalDate.now().with(
TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)
);// This return 2018-01-01
LocalDate sunday = firstMondayOfMonth.minusDays(1);//This return 2017-12-31
To test with November 2017 you can use LocalDate.of instead LocalDate.now() like this :
LocalDate firstMondayOfMonth = LocalDate.of(2017, Month.NOVEMBER, 1).with(
TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)
);// This return 2017-11-06
LocalDate firstSunday = firstMondayOfMonth.minusDays(1);// This return 2017-11-05
tl;dr
YearMonth
.now() // Current year-month. Tip: Better to pass the optional time zone, as shown further down in this Answer.
.atDay( 1 ) // First of the current month.
.with( TemporalAdjusters.nextOrSame( DayOfWeek.MONDAY ) ) // Move from first day of month to the following Monday, or stay on the first if it already a Monday.
.minusDays( 1 ) // Move back one day from Monday to get a Sunday. May be in current month or in previous month.
java.time
You are using troublesome old date-date classes that are now legacy, supplanted by the java.time classes.
Determining the current month means determining the current date. Determining the current date requires a time zone. For any given moment, the date varies around the globe by zone.
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
The YearMonth class represent the entire month.
YearMonth currentYearMonth = YearMonth.now( z ) ;
From that we can get the first of the month.
LocalDate firstOfMonth = currentYearMonth.atDay( 1 ) ;
We can move to a certain day of the week by calling on a TemporalAdjuster.
LocalDate firstMondayOfMonth = firstOfMonth.with( TemporalAdjusters.nextOrSame( DayOfWeek.MONDAY ) ) ;
LocalDate sundayBeforeFirstMondayOfMonth = firstMondayOfMonth.with( TemporalAdjusters.previous( DayOfWeek.SUNDAY ) ) ;
Logically, that last line could be replaced with .minusDays( 1 ) as we know the previous Sunday immediately precedes our Monday by definition.
In the code below, first we get the first monday in the month. Then we just subtract 1 day.
// input
int year = 2017;
int month = Calendar.NOVEMBER;
// get first monday of the month
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
c.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
c.set(Calendar.MONTH, month);
c.set(Calendar.YEAR, year);
System.out.println("Date " + c.getTime());
// subtract 1
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println("Date " + c.getTime());
Try this:
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
calendar.add(Calendar.DATE, -1);
System.out.println(calendar.getTime());
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek( Calendar.MONDAY); //Monday is first day of a week
c.setMinimalDaysInFirstWeek( 1); //first week of month is the week that has at least one day in this month
//c.setMinimalDaysInFirstWeek( 7); //first week of month must be a full week
c.set(Calendar.WEEK_OF_MONTH, 1); //move to first week of month
System.out.println("Date " + c.getTime());
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //move to Monday
System.out.println("Date " + c.getTime());
c.add( Calendar.DAY_OF_MONTH, -1); //go back one day
System.out.println("Date " + c.getTime());
Choose one of the c.setMinimalDaysInFirstWeek() method depending on what the first week of month means to you.
In Java 8, you can use the below code:
public static void getSundayBeforeFirstMondayOfMonth(LocalDate date){
date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)).minusDays(1);
}
And, call the above method like below as per the requirement:
public static void callerMethod(){
// Call with Current Date
getSundayBeforeFirstMondayOfMonth(LocalDate.now());
//Call with Custom Date
LocalDate customDate = LocalDate.parse("27-11-2017", DateTimeFormatter.ofPattern("DD-MM-YYYY"));
getSundayBeforeFirstMondayOfMonth(customDate);
}

How to get week of selected date in java?

How to get week of particular selected date?
For Example:
My week will start from Monday and ends on Sunday.
So lets say i have selected 25 July 2017. So i want what was the date on monday of that week and what is the date on upcoming Sunday of that week.
The answer should be :: Monday -- 24 July 2017 AND Sunday-- 30 July 2017.
I am not able to find a simple way to get it.
You can see this. It is for the present date.
Calendar cal = Calendar.getInstance();
int week = cal.get(Calendar.WEEK_OF_MONTH);
int day = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(day);
Date mondayDate = null;
if (day > 2) {
int monday = day - 2;
cal.add(Calendar.DATE, -monday);
mondayDate = cal.getTime();
} else {
// cal.add(Calendar.DATE,);
mondayDate = cal.getTime();
}
int sunday = 7 - day + 1;
cal.add(Calendar.DATE, +sunday);
Date sundaydate = cal.getTime();
System.out.println(mondayDate);
System.out.println(sundaydate);
}
In this, we are finding the day of the week.Today we will get
day=2.
Now for monday,we will first check days.
if day=1, means it is sunday.
if day=2, means it is monday.
so for day>2, we are getting date of (day-2) days back. For today, day=1. hence mondaydate= 23 July,2017.
Similarily for sunday, we are getting date of (7-day+1) days later. For today, sunday=5, so after +6, sundaydate= 31 july,2017
Hope this helps :)
You can get like this :
String date = (String) android.text.format.DateFormat.format("dd", date);
String dayOfTheWeek = (String) DateFormat.format("EEEE", date);
For next Sunday you can calculate as per dayOfTheWeek.

Get the first Monday of a month

I want to get the day on which the first Monday of a specific month/year will be.
What I have:
I basically have two int variables, one representing the year and one representing the month.
What I want to have:
I want to know the first Monday in this month, preferably as an int or Integer value.
For example:
I have 2014 and 1 (January), the first Monday in this month was the 6th, so I want to return 6.
Problems:
I thought I could do that with the Calendar but I am already having trouble setting up the calendar with only Year and Month available. Furthermore, I'm not sure how to actually return the first Monday of the month/year with Calendar.
I already tried this:
Calendar cal = Calendar.getInstance();
cal.set(this.getYear(),getMonth(), 1);
int montag = cal.getFirstDayOfWeek();
for( int j = 0; j < 7; j++ ) {
int calc = j - montag;
if( calc < 0 ) {
calc += 6;
}
weekDays[calc].setText(getDayString(calc));
}
Java.time
Use java.time library built into Java 8 and TemporalAdjuster. See Tutorial.
import java.time.DayOfWeek;
import java.time.LocalDate;
import static java.time.temporal.TemporalAdjusters.firstInMonth;
LocalDate now = LocalDate.now(); //2015-11-23
LocalDate firstMonday = now.with(firstInMonth(DayOfWeek.MONDAY)); //2015-11-02 (Monday)
If you need to add time information, you may use any available LocalDate to LocalDateTime conversion like
firstMonday.atStartOfDay() # 2015-11-02T00:00
getFirstDayOfWeek() returns which day is used as the start for the current locale. Some people consider the first day Monday, others Sunday, etc.
This looks like you'll have to just set it for DAY_OF_WEEK = MONDAY and DAY_OF_WEEK_IN_MONTH = 1 as that'll give you the first Monday of the month. To do the same for the year, first set the MONTH value to JANUARY then repeat the above.
Example:
private static Calendar cacheCalendar;
public static int getFirstMonday(int year, int month) {
cacheCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cacheCalendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
cacheCalendar.set(Calendar.MONTH, month);
cacheCalendar.set(Calendar.YEAR, year);
return cacheCalendar.get(Calendar.DATE);
}
public static int getFirstMonday(int year) {
return getFirstMonday(year, Calendar.JANUARY);
}
Here's a simple JUnit that tests it: http://pastebin.com/YpFUkjQG
First of all you should know the latest version of java i.e. JAVA8
Get familiar with LocalDate in JAVA8
Then only go through below code
public class Test {
public static void main(String[] args) {
LocalDate date=LocalDate.of(2014,1, 1);
for(int i=0;i<date.lengthOfMonth();i++){
if("Monday".equalsIgnoreCase(date.getDayOfWeek().toString())){
break;
}else{
date=date.plusDays(1);
}
}
System.out.println(date.getDayOfMonth());
}
}
Joda-Time
The Joda-Time library offers a class, LocalDate, for when you need only a date without a time-of-day. The method getDayOfWeek returns a number you can compare to the constant MONDAY.
LocalDate localDate = new LocalDate( year, month, 1 );
while ( localDate.getDayOfWeek() != DateTimeConstants.MONDAY ) {
localDate = localDate.plusDays( 1 );
}
int firstMonday = localDate.getDayOfMonth();
Immutable Syntax
For thread-safety, Joda-Time uses immutable objects. So rather than modify field values in an existing object, we create a new instance based on the original.
java.time
As another answer by Abhishek Mishra says, the new java.time package bundled with Java 8 also offers a LocalDate class similar to Joda-Time.
The method getFirstDayOfWeek() is not helpful. Quoting its javadoc:
Gets what the first day of the week is; e.g., SUNDAY in the U.S., MONDAY in France
The following tested method uses modulus arithmetic to find the day of the month of the first Monday:
public static long getMondaysDay(int year, int month) {
try {
Date d = new SimpleDateFormat("d-M-yyyy").parse("1-" + month + "-" + year);
long epochMillis = d.getTime() + TimeZone.getDefault().getOffset(d.getTime());
return (12 - TimeUnit.MILLISECONDS.toDays(epochMillis) % 7) % 7;
} catch (ParseException ignore) { return 0; } // Never going to happen
}
Knowing that the first day of the epoch was Thursday, this works by using modulus arithmetic to calculate the day of the epoch week, then how many days until the next Monday, then modulus again in case the first falls before Thursday. The magic number 12 is 4 (the number of days from Thursday to Monday) plus 1 because days of the month start from 1 plus 7 to ensure positive results after subtraction.
The simplest way is:
LocalDate firstSundayOfNextMonth = LocalDate
.now()
.with(firstDayOfNextMonth())
.with(nextOrSame(DayOfWeek.MONDAY));
Here is a general function to get the nth DAY_OF_WEEK of a given month. You can use it to get the first Monday of any given month.
import java.util.Calendar;
public class NthDayOfWeekOfMonth {
public static void main(String[] args) {
// get first Monday of July 2019
Calendar cal = getNthDayOfWeekOfMonth(2019,Calendar.JULY,1,Calendar.MONDAY);
System.out.println(cal.getTime());
// get first Monday of August 2019
cal = getNthDayOfWeekOfMonth(2019,Calendar.AUGUST,1,Calendar.MONDAY);
System.out.println(cal.getTime());
// get third Friday of September 2019
cal = getNthDayOfWeekOfMonth(2019,Calendar.SEPTEMBER,3,Calendar.FRIDAY);
System.out.println(cal.getTime());
}
public static Calendar getNthDayOfWeekOfMonth(int year, int month, int n, int dayOfWeek) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.YEAR,year);
cal.set(Calendar.MONTH,month);
cal.set(Calendar.DAY_OF_MONTH,1);
int dayDiff = dayOfWeek-cal.get(Calendar.DAY_OF_WEEK);
if (dayDiff<0) {
dayDiff+=7;
}
dayDiff+=7*(n-1);
cal.add(Calendar.DATE, dayDiff);
return cal;
}
}
Output:
Mon Jul 01 00:00:00 EDT 2019
Mon Aug 05 00:00:00 EDT 2019
Fri Sep 20 00:00:00 EDT 2019
Lamma Date library is very good for this use case.
#Test
public void test() {
assertEquals(new Date(2014, 1, 6), firstMonday(2014, 1));
assertEquals(new Date(2014, 2, 3), firstMonday(2014, 2));
assertEquals(new Date(2014, 3, 3), firstMonday(2014, 3));
assertEquals(new Date(2014, 4, 7), firstMonday(2014, 4));
assertEquals(new Date(2014, 5, 5), firstMonday(2014, 5));
assertEquals(new Date(2014, 6, 2), firstMonday(2014, 6));
}
public Date firstMonday(int year, int month) {
Date firstDayOfMonth = new Date(year, month, 1);
return firstDayOfMonth.nextOrSame(DayOfWeek.MONDAY);
}
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MMM/dd/YYYY");
calendar.set(Calendar.MONTH,Calendar.JUNE);
calendar.set(Calendar.DAY_OF_MONTH,1);
int day = (Calendar.TUESDAY-calendar.get(Calendar.DAY_OF_WEEK));
if(day<0){
calendar.add(Calendar.DATE,7+(day));
}else{
calendar.add(Calendar.DATE,day);
}
System.out.println("First date is "+sdf.format(calendar.getTime()));
Get the All Monday of a month
public class AllMonday {
public static void main(String[] args){
System.out.println(weeksInCalendar(YearMonth.now()));
}
public static List<LocalDate> weeksInCalendar(YearMonth month) {
List<LocalDate> firstDaysOfWeeks = new ArrayList<>();
for (LocalDate day = firstDayOfCalendar(month);
stillInCalendar(month, day); day = day.plusWeeks(1)) {
firstDaysOfWeeks.add(day);
}
return firstDaysOfWeeks;
}
private static LocalDate firstDayOfCalendar(YearMonth month) {
DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.of(1);
System.out.println( month.atDay(1).with(FIRST_DAY_OF_WEEK));
return month.atDay(1).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
}
private static boolean stillInCalendar(YearMonth yearMonth, LocalDate day) {
System.out.println(!day.isAfter(yearMonth.atEndOfMonth()));
return !day.isAfter(yearMonth.atEndOfMonth());
}
}

get startday of month and endday of month using calendar class in Java

Given a year and a month; I want to get two Date Objects. one for startDate of the month and one for the end Date of the month. I have it implemented here and it works. but this looks too verbose, and I am wondering if there is a neat solution to this;
Eg given March 2014,
start Date will be March 01 and end Date will be March 31 ( as Date objects with millisecond precision)
public setDates(int month,int year) {
Calendar calendar = Calendar.getInstance();
// Use the calendar to get the startDate and endDate of this Invoice.
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH,month);
//set start date
calendar.set(Calendar.DAY_OF_MONTH,
calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
calendar.set(Calendar.HOUR_OF_DAY,
calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE,
calendar.getActualMinimum(Calendar.MINUTE));
calendar.set(Calendar.SECOND,
calendar.getActualMinimum(Calendar.SECOND));
calendar.set(Calendar.MILLISECOND,
calendar.getActualMinimum(Calendar.MILLISECOND));
this.startDate = calendar.getTime();
//endDate start date
calendar.set(Calendar.DAY_OF_MONTH,
calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
calendar.set(Calendar.HOUR_OF_DAY,
calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE,
calendar.getActualMaximum(Calendar.MINUTE));
calendar.set(Calendar.SECOND,
calendar.getActualMaximum(Calendar.SECOND));
calendar.set(Calendar.MILLISECOND,
calendar.getActualMaximum(Calendar.MILLISECOND));
this.endDate = calendar.getTime();
}
You can make this code considerably simpler by making some assumptions:
The first day of the month is always day 1
The minimum hour will always be 0
... etc
You can then find the last millisecond of the month by adding one month and subtracting a millisecond.
So the code could look like this:
// Note year/month reversal: try to consistently use larger units first. It
// makes for a cleaner API.
public setDates(int year, int month, TimeZone zone) {
Calendar calendar = Calendar.getInstance(zone);
// Do you really want 0-based months, like Java has? Consider month - 1.
calendar.set(year, month, 1, 0, 0, 0);
calendar.clear(Calendar.MILLISECOND);
startDate = calendar.getTime();
// Get to the last millisecond in the month
calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.MILLISECOND, -1);
endDate = calendar.getTime();
}
To use an exclusive upper bound (as I'd recommend), just get rid of the calendar.add(Calendar.MILLISECOND, -1) near the end.
Oh, and I'd thoroughly recommend using Joda Time instead of java.util.Date etc - it's a much cleaner API.
Take March 1st. Add 1 to the month field. Then subtract 1 day.
Here is your last day of the month.
The first day is clear, it is 1st of month of year.
Verbose is OK, there's no much less verbose code version
(in JDK <= 7) if you stick to Java's built-in libraries.
use JODA, please.
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Period;
public class Dates {
/**
* #param args
*/
public static void main(String[] args) {
//without JODA
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Helsinki"));
calendar.set(1921, 4, 1, 0, 0, 0);
calendar.clear(Calendar.MILLISECOND);
Date startDate = calendar.getTime();
System.out.println(startDate);
calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.MILLISECOND, -1);
Date endDate = calendar.getTime();
System.out.println(endDate);
/*
* Sat Apr 30 19:20:08 BRT 1921
* Tue May 31 19:20:07 BRT 1921
*/
//with JODA
DateTimeZone zone = DateTimeZone.forTimeZone(TimeZone.getTimeZone("Europe/Helsinki"));
DateTime dt = new DateTime(1921, 4, 1, 0, 0, 0, 0, zone);
DateTime plusPeriod = dt.plus(Period.months(1)).minus(Period.millis(1));
System.out.println(dt);
System.out.println(plusPeriod);
/*
* 1921-04-01T00:00:00.000+01:39:52
* 1921-04-30T23:59:59.999+01:39:52
*/
}
}

Creating java date object from year,month,day

int day = Integer.parseInt(request.getParameter("day")); // 25
int month = Integer.parseInt(request.getParameter("month")); // 12
int year = Integer.parseInt(request.getParameter("year")); // 1988
System.out.println(year);
Calendar c = Calendar.getInstance();
c.set(year, month, day, 0, 0);
b.setDob(c.getTime());
System.out.println(b.getDob());
Output is:
1988
Wed Jan 25 00:00:08 IST 1989
I am passing 25 12 1988 but I get 25 Jan 1989. Why?
Months are zero-based in Calendar. So 12 is interpreted as december + 1 month. Use
c.set(year, month - 1, day, 0, 0);
That's my favorite way prior to Java 8:
Date date = new GregorianCalendar(year, month - 1, day).getTime();
I'd say this is a bit cleaner than:
calendar.set(year, month - 1, day, 0, 0);
java.time
Using java.time framework built into Java 8
int year = 2015;
int month = 12;
int day = 22;
LocalDate.of(year, month, day); //2015-12-22
LocalDate.parse("2015-12-22"); //2015-12-22
//with custom formatter
DateTimeFormatter.ofPattern formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate.parse("22-12-2015", formatter); //2015-12-22
If you need also information about time(hour,minute,second) use some conversion from LocalDate to LocalDateTime
LocalDate.parse("2015-12-22").atStartOfDay() //2015-12-22T00:00
Java's Calendar representation is not the best, they are working on it for Java 8. I would advise you to use Joda Time or another similar library.
Here is a quick example using LocalDate from the Joda Time library:
LocalDate localDate = new LocalDate(year, month, day);
Date date = localDate.toDate();
Here you can follow a quick start tutorial.
See JavaDoc:
month - the value used to set the MONTH calendar field. Month value is
0-based. e.g., 0 for January.
So, the month you set is the first month of next year.
Make your life easy when working with dates, timestamps and durations. Use HalDateTime from
http://sourceforge.net/projects/haldatetime/?source=directory
For example you can just use it to parse your input like this:
HalDateTime mydate = HalDateTime.valueOf( "25.12.1988" );
System.out.println( mydate ); // will print in ISO format: 1988-12-25
You can also specify patterns for parsing and printing.

Categories

Resources