Java GregorianCalendar What am I doing wrong? Wrong date? - java

Hello I have a problem with GregorianCalendar.
What is wrong in there?
How outcome is 2010/6/1 and not 2010/05/31?
package test;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Main {
public static void main(String[] args) {
Calendar cal = new GregorianCalendar(2010, 5, 31);
System.out.println(cal.get(Calendar.YEAR) + "/" + cal.get(Calendar.MONTH) + "/" + cal.get(Calendar.DAY_OF_MONTH));
}
}

Java counts months from 0, so 5 is June. It's always safer to use the constants. So I would write:
Calendar cal = new GregorianCalendar(2010, Calendar.MAY, 31);
The same applies to your calendar print out. If you do cal.get(Calendar.MONTH) you get 6 meaning JULY.

This is because month number is zero-based, so you are trying to set 31st of June, but June is only 30 days, so it gets converted to 1st of July.

Toadd to what the above answers, since there is no 31st day in June the Calendar promotes it to the next valid day because Calendar.setLenient is true by default.

Related

How to get the Date Of Birth given number of years months and days of a person in java

Given year, month and days of a person, need to get Date of Birth -
Example - 19 years 1 moth and 2 days
16-Sept-2010 (have calculated it manually, may not be accurate)
LocalDateTime.now().minusYears(years).minusMonths(months).minusDays(days)
I would go with java.time.LocalDate and java.time.Period class. Calling minus methods might not be optimal as it will create new object for every method invocation (classes like LocalDate, LocalDateTime are immutable) :
Period period = Period.of(19, 1, 2); //period of 19 years, 1 month, 2 days
LocalDate birthday = LocalDate.now().minus(period); // compute the birthday
String formattedDate = birthday.format(DateTimeFormatter.ofPattern("dd-MMMM-YYYY", Locale.UK));
System.out.println(formattedDate);
The output is :
15-September-2000
Basically, you can use the modern API for dates and times java.time and especially the class LocalDate. It has methods to add or subtract units of time, such as days, months and years.
public static void main(String[] args) {
System.out.println("Imagine someone being 19 years, 1 months and 2 days old today...");
LocalDate birthday = getBirthdayFromAge(19, 1, 2);
System.out.println("Then this person was born on "
+ birthday.format(DateTimeFormatter.ISO_DATE));
}
public static LocalDate getBirthdayFromAge(int years, int months, int days) {
return LocalDate.now()
.minusDays(days)
.minusMonths(months)
.minusYears(years);
}
This outputs
Imagine someone being 19 years, 1 months and 2 days old today...
Then this person was born on 2000-09-15
You should to transform year to Timestamp,month to Timestamp, day to Timestamp.
Diff this with current timestamp and you will get birth date Timestamp
Here is quick fix for you. Please check following code.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Birthdate {
public static void main(String[] args) {
Birthdate calUsage = new Birthdate();
calUsage.subtractTime();
}
private void subtractTime() {
Calendar calendar = new GregorianCalendar();
String pattern = "yyyy-MMMM-dd";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String date = sdf.format(calendar.getTime());
System.out.println("Current Date::" + date);
calendar.add(Calendar.MONTH, -1);
calendar.add(Calendar.DAY_OF_YEAR, -2);
calendar.add(Calendar.YEAR, -19);
date = sdf.format(calendar.getTime());
System.out.println("Birthdate ::" + date);
}
}
Hope this solution works.

Get third friday of a month

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);

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());
}
}

A scenario about the calendar in Java in which explicitly setting a date leads to some diffrent result

Let's look at the following code snippet in Java.
package demo;
import java.util.Calendar;
final public class Main
{
public static void main(String[] args)
{
Calendar cal = Calendar.getInstance();
cal.set(2011, 11, 11); //Setting a date to itself.
System.out.println(cal.get(Calendar.YEAR) + " "
+ cal.get(Calendar.WEEK_OF_YEAR) + "
" + cal.get(Calendar.DAY_OF_YEAR));
}
}
In the above simple code, I'm temporarily (and explicitly) setting the current date to itself which is 2011-11-11 using the method cal.set(2011, 11, 11);. Accordingly, I get the output 2011 51 345, the current year 2011, the week of the year 51 and the day of the year 345.
When I leave a comment on that line which is cal.set(2011, 11, 11);, I get the result, 2011 46 315 the current year, the current week of the year and the current day of the year respectively which is different from the earlier result.
[Here, I'm not setting any date. The statement cal.set(2011, 11, 11); in the above code is commented out and the system is automatically retrieving the current date which is 2011-11-11].
In both the cases, the same date is used which is 2011-11-11 still the result obtained is different in both of the cases. Why?
The month value is 0-based. If you meant November, use:
cal.set(2011, 10, 11);
See the Calendar javadocs.
The month is zero indexed in Java. You're setting it to December 11th when you choose month 11.

Fixed length of month and day in date format?

Is there any way to format Date object to made fixed length of Day and Month in order to have good alignment in a column?
For example:
15 May 2010
10 January 2010
Instead of
15 May 2010
10 January 2010
Thanks!
Have a look at the java.util.Formatter class whose format method is the same as String.format(...) and similar to System.out.printf.
For example:
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class FormatDateCalendar {
public static final String FORMAT_STRING = "%1$-3td %1$-9tB %1$tY";
public static void main(String[] args) {
Calendar c1 = new GregorianCalendar(2011, Calendar.FEBRUARY, 3);
Calendar c2 = new GregorianCalendar(2010, Calendar.MAY, 15);
Date today = new Date();
System.out.printf(FORMAT_STRING + "%n", c1);
System.out.printf(FORMAT_STRING + "%n", c2);
System.out.printf(FORMAT_STRING + "%n", today);
}
}

Categories

Resources