I am having problems with the Calendar Class.
Calendar cal = Calendar.getInstance ();
int iYear = cal.get (Calendar.YEAR); // get the current year
int iMonth = cal.get (Calendar.MONTH); // month...
int iDay = cal.get (Calendar.); // current day in the month
This... No Workie!! :-(
I used the debugger and found that the YEAR and the DAY_OF_MONTH are correct,
however, the MONTH is 1 (January) when it SHOULD BE 2 (February).
Here is where it gets even more WEIRD:
I then tried cal.clear ();
followed by cal.set (2014, 2, 27); // Today's Date - Feb 27, 2014
and the month was still 1 (i.e. January)
I set the date to days in January, (2014, 1, 1), (2014, 1, 16),etc
It correctly gave me a 1 for the month
After reading and trying many things (and pulling my hair out..)
I set it to a date in the future, my Birthday (2014, 5, 23) and other days.
For those dates, Month was correctly set to 5 (May)
Month in Calendar begins at 0, which means 0 is January, 1 is February, etc.
Java Date and Time API sucks. Use Joda-Time instead.
use constants in Calendar for month: Calendar.JANUARY etc
For example:
cal.set(2014, Calendar.FEBRUARY, 27);
Please see the description provided for MONTH Constant in Calendar Class.
Calendar.MONTH
public static final int MONTH
Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
So if you want to set the date in calendar than use below code snippet.
cal.set(2014, Calendar.FEBRUARY, 28);
I think it will help you.
tl;dr
LocalDate.now()
.getYear()
java.time
The modern approach uses the industry-leading java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Parts
Interrogate for the parts as needed.
int dayOfMonth = ld.getDayOfMonth() ;
int month = ld.getMonthValue() ;
int year = ld.getYear() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Let try this simple program:
import java.util.Calendar;
class CalendarExample {
public static void main(String args[]) {
Calendar calendar = Calendar.getInstance();
System.out.println("Current Date : " + calendar.get(Calendar.DATE));
System.out.println("Current Month : " + calendar.get(Calendar.MONTH));
System.out.println("Current Year : " + calendar.get(Calendar.YEAR));
System.out.print("Current Time : ");
System.out.print(calendar.get(Calendar.HOUR) + ":");
System.out.print(calendar.get(Calendar.MINUTE) + ":");
System.out.print(calendar.get(Calendar.SECOND));
}
}
You get the o/p:
Current Date : 28
Current Month : 1
Current Year : 2014
Current Time : 11:18:3
In Calender class Jan as constant int is 0 , Feb is 1 ... .month constant int value is from 0,1,2..
Related
I need get the same day in this year.
Example: Now is 2019 year and the variable contains value 15 July 2022, so I need to get 15 July 2019 then. It works for all dates except February when it has an extra day in one year and doesn't have this day in this year, example: 29 February 2020 will return me the next day: 1 March 2019, but I need in this case to return the previous day: 28 February 2019. How I can adjust my logic so that it will work in this way?
public static java.util.Date getThisDateInThisYear(java.util.Date date) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
Date today = new Date();
GregorianCalendar gcToday = new GregorianCalendar();
gcToday.setTime(today);
gc.set(GregorianCalendar.YEAR, gcToday.get(GregorianCalendar.YEAR));
return gc.getTime();
}
first calc the difference of years and add the result to date
public Date getThisDateInThisYear(Date date) {
Calendar c = Calendar.getInstance();
int thisYear = c.get(Calendar.YEAR)
c.setTime(date);
int diff = thisYear - c.get(Calendar.YEAR);
c.add(Calendar.YEAR, diff);
return c.getTime();
}
I tested with 2016-02-29 and 2020-02-29, and both return 2019-02-28.
tl;dr
Use modern java.time classes. Never use Date/Calendar.
29 February 2020 will return me next day: 1st March 2019
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.of( 2020 , Month.FEBRUARY , 29 ) // Specify a date. Here, Leap Day of 2020. Returns a `LocalDate` object.
.minusYears( 1 ) // Intelligently move backwards in time one year. Returns another `LocalDate` object, per immutable objects pattern.
.toString() // Generate text representing the value of this date, in standard ISO 8601 format of YYYY-MM-DD.
When run at IdeOne.com:
2019-02-28
Avoid legacy date-time classes
You are using terrible date-time classes that are now legacy, supplanted entirely by the java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 2020 , 2 , 29 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety. Ditto for Year & YearMonth.
LocalDate ld = LocalDate.of( 2020 , Month.FEBRUARY , 29 ) ;
Date-time math
You can do date-time math in a few ways with *java.time. One way is by calling plus or minus and passing a Period or Duration. Another way is calling the convenience methods such as plusYears or minusYears.
The LocalDate class seems to give just the behavior you want with these methods.
To be clear:
2020 is a Leap Year. So 2020-02-29 is a valid date.
2018, 2019, and 2021 are not. The 29th is not a valid date in these years.
See the examples below run live at IdeOne.com.
From leap year
Let's start on Leap Day, the 29th, then add a year and subtract a year. We expect to see 28th on both.
LocalDate leapDay2020 = LocalDate.of( 2020 , Month.FEBRUARY , 29 );
LocalDate yearBeforeLeap = leapDay2020.minusYears( 1 );
LocalDate yearAfterLeap = leapDay2020.plusYears( 1 );
System.out.println( "leapDay2020.toString(): " + leapDay2020 );
System.out.println( "yearBeforeLeap.toString(): " + yearBeforeLeap );
System.out.println( "yearAfterLeap.toString(): " + yearAfterLeap );
Indeed that is what we get.
leapDay2020.toString(): 2020-02-29
yearBeforeLeap.toString(): 2019-02-28
yearAfterLeap.toString(): 2021-02-28
From non-Leap Year
Now let's start in a non-Leap Year on the 28th of February, then add & subtract a year. We expect to see 28th in all three. The 29th in the Leap year of 2020 is ignored.
LocalDate nonLeap2019 = LocalDate.of( 2019 , Month.FEBRUARY , 28 );
LocalDate yearBeforeNonLeapIntoNonLeap = nonLeap2019.minusYears( 1 );
LocalDate yearBeforeNonLeapIntoLeap = nonLeap2019.plusYears( 1 );
System.out.println( "nonLeap2019.toString(): " + nonLeap2019 );
System.out.println( "yearBeforeNonLeapIntoNonLeap.toString(): " + yearBeforeNonLeapIntoNonLeap );
System.out.println( "yearBeforeNonLeapIntoLeap.toString(): " + yearBeforeNonLeapIntoLeap );
nonLeap2019.toString(): 2019-02-28
yearBeforeNonLeapIntoNonLeap.toString(): 2018-02-28
yearBeforeNonLeapIntoLeap.toString(): 2020-02-28
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Also you can check if year is leap year based on that you can subtract the date
public static boolean isLeapYear(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
I don't see any problem with java.util.Calendar. In JDK 1.8 this Java class got a major rework. So the following example code works fine:
SimpleDateFormat sf = new SimpleDateFormat("dd MMM yyyy");
Date date=sf.parse("29 Feb 2020");
System.out.println("date="+date);
Calendar calendar=Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.YEAR, -1);
System.out.println("date="+calendar.getTime());
calendar.add(Calendar.YEAR, 1);
System.out.println("date="+calendar.getTime());
It gives the same result as Basil Bourque wants it to have:
date=Sat Feb 29 00:00:00 CET 2020
date=Thu Feb 28 00:00:00 CET 2019
date=Fri Feb 28 00:00:00 CET 2020
Basically the Java class now uses the same ZoneInfo etc.. classes as the new classes also do.
I'm need to do a method that returns the position of actual day in the next month.
for today (20/12/2016)
I need to call this method whit today date
The return given must to be (17/01/2016)
This method must return the third Tuesday of the next month
Is the 4 week of this month, but I need the Third Tuesday.
I try to use Calendar.MONTH, Calendar.WEEK_OF_MONTH, Calendar.DAY_OF_WEEK but I can't get the third, I always get the fourth.
Some thing like this:
public static Date getNextMonthDayOfWeel(Date d) {
Calendar c = Calendar.getInstance();
c.setTime(d);
int week = c.get(Calendar.WEEK_OF_MONTH);
int day = c.get(Calendar.DAY_OF_WEEK);
//// this block
if(!firstWeekOfMonthHad(day)){
week++;
}
//// this block
c.setFirstDayOfWeek(Calendar.SUNDAY);
c.add(Calendar.MONTH, 1);
c.set(Calendar.WEEK_OF_MONTH, week);
c.set(Calendar.DAY_OF_WEEK, day);
return c.getTime();
}
How can I get if the first week of the month have the specific day of the week?
If you use Java 8 or later, it is as simple as:
LocalDate.now()
.plusMonths(1)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.TUESDAY))
.plusWeeks(3);
tl;dr
LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) // Get current date in this particular time zone.
.plusMonths( 1 ) // Move to equivalent date in the month after.
.with(
TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.TUESDAY ) // Move to the ordinal number occurrence of a day-of-week within this month.
)
Details
You seem to be asking for the third Tuesday of next month.
The Answer by Mellgren is good, but here's a variation on that idea using a more appropriate TemporalAdjuster.
Avoid legacy classes
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
Move to the next month.
LocalDate monthLater = today.plusMonths( 1 );
TemporalAdjuster
To move to the third Tuesday of the month, use an implementation of TemporalAdjuster found in the TemporalAdjusters class.
For an ordinal day-of-week within a month like “Third Tuesday of the month” or “First Thursday of the month”, Java offers a specific adjuster: TemporalAdjusters.dayOfWeekInMonth. Pass the ordinal number such as 3 for “third”, and a DayOfWeek enum object constant such as DayOfWeek.TUESDAY.
TemporalAdjuster ta = TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.TUESDAY ); // Pass ordinal number and `DayOfWeek`.
LocalDate thirdTuesdayOfNextMonth = monthLater.with( ta );
Dump to console.
System.out.println( "today is " + today + " in zone " + z );
System.out.println( "Third Tuesday of next month is " + thirdTuesdayOfNextMonth );
See this code run live at IdeOne.com.
Today is 2018-01-20 in zone America/Montreal
Third Tuesday of next month is 2018-02-20
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I wrote simple java program in which I get day of month, days in month and month
see below code :
//Calendar calendar = Calendar.getInstance();
Calendar calendar = new GregorianCalendar();
log.info("day of month: "+calendar.get(Calendar.DAY_OF_MONTH));
calendar.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH);
log.info("days in month: "+calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
log.info("month: "+calendar.get(Calendar.MONTH));
Running above code I get this output:
day of month: 7
days in month: 31
month: 2
But when I put below statement
log.info("month: "+calendar.get(Calendar.MONTH));
before
log.info("day of month: "+calendar.get(Calendar.DAY_OF_MONTH));
I get this output: (which is what I want)
day of month: 7
days in month: 31
month: 5
Can any body help me understand why I get month: 2 ?
Youre setting the Calendar field to Calendar.MONTH (value 2) here
calendar.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH);
^
You can do this
calendar.set(2014, Calendar.JUNE, 1);
although the Month 5 is June (since month field starts from 0 for Calendar) which only has 30 days
Look at the source code of Calendar.java of JDK.
public final static int MONTH = 2;
Here, Calendar.MONTH = 2, Calendar.YEAR=1 and Calendar.DAY_OF_MONTH = 5. You set these constant value to calender using set method like.
calendar.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH);
| | |
1 2 5
tl;dr
LocalDate.now()
.getDayOfMonth()
…and…
YearMonth.from(
LocalDate.now()
).lengthOfMonth() // .getMonthValue() .getYear()
java.time
The modern approach uses the industry-leading java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Parts
Interrogate for the parts as needed.
int dayOfMonth = ld.getDayOfMonth() ;
int month = ld.getMonthValue() ;
int year = ld.getYear() ;
YearMonth
To work with the month as a whole, use YearMonth class.
YearMonth ym = YearMonth.from( ld ) ;
Ask for length of month.
int lengthOfMonth = ym.lengthOfMonth() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I just started going to university and basically just started using java and I want to know how to make a code that calculates the days between two dates but without the use of programs that take milliseconds and such things that I have seen in other answers.So this is the code I have created but it doesnt work perfectly it misses one day most of the times or something like that.Please I really need your help
Use a SimpleCalendar or GregorianCalendar classes...
but basing on what you posted, I'm unsure how to best suggest using those two... i'll draft a simple example shortly.
After some thought I'll just leave this here Difference in days between two dates in Java?
Taken from: http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar_text5.htm
An approach could be to calculate the number of days from a fixed time for both dates and then just subtract those days. This will give you the difference of days between date 1 and date 2
The following method returns the number of days passed since 0 January 0 CE
public int calculateDate( int day, int month, int year) {
if (month < 3) {
year--;
month = month + 12;
}
return 365 * year + year/4 - year/100 + year/400 + ((month+1) * 306)/10 + (day - 62);
}
In you code now you should calculate the number of days since 0BC for both dates and then subtract them:
public void run() {
....
int dayDifference = calculateDate(day1, month1, year1) - calculateDate(day2, month2, year2);
....
}
tl;dr
java.time.temporal.ChronoUnit.DAYS.between(
LocalDate.of( 2012 , Month.MARCH , 23 ) ,
LocalDate.of( 2012 , Month.MAY , 17 )
)
55
java.time
The modern approach uses java.time classes that supplant the troublesome old legacy date-time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
ChronoUnit.DAYS
To get a count of days between two dates, call on the ChronoUnit enum object DAYS.
long days = ChronoUnit.DAYS.between( earlierLocalDate , laterLocalDate ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I'm using the GregorianCalendar in Java, and I am wondering how I can use this to check whether or not a date is valid (E.g.: to check if Feb 29th is only in leap year, to check if the date is no sooner than the current data, etc).
I have created a GregorianCalendar object and passed it the values of the data I would like to check as follows:
GregorianCalendar cal1 = new GregorianCalendar(day,month,year);
If the date is valid, I'd like to return true. How could I do this?
Basic Idea: if you try to set the invalid date to Calendar instance, it would make it correct one,
For example if you set 45 as date it would not be the same once you set and retrieve
public boolean isValid(int d, int m, int y){
//since month is 0 based
m--;
//initilizes the calendar instance, by default the current date
Calendar cal = Calendar.getInstance();
//resetting the date to the one passed
cal.set(Calendar.YEAR, y);
cal.set(Calendar.MONTH, m);
cal.set(Calendar.DATE, d);
//now check if it is the same as we set then its valid, not otherwise
if(cal.get(Calendar.DATE)==d &&cal.get(Calendar.MONTH) ==m && cal.get(Calendar.YEAR) ==y){
return true;
}
//changed so not valid
return false;
}
Check that after creation, the day, month and year is still the same as the original values you passed. If the original values are incorrect, the date will get adjusted accordingly. E.g.. if you pass (29, 1, 2011) - note that the month value is 0-based so 1 is for February -, you will get back (1, 3, 2011).
tl;dr
java.time.LocalDate.of( 2018 , 2 , 31 )
➙ catch DateTimeException for invalid day-of-month number.
java.time
The GregorianCalendar class has been supplanted by the ZonedDateTime class as part of java.time built into Java 8 and later. A new method has been added to the old class for conversion.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
You want a date-only value, so use LocalDate, without time-of-day and without time zone.
You can extract a LocalDate from a ZonedDateTime time.
LocalDate ld = zdt.toLocalDate() ;
You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Valid value
to check if Feb 29th is only in leap year
The documentation for `LocalDate.of( year , month , day ) says:
The day must be valid for the year and month, otherwise an exception will be thrown.
So catch the DateTimeException.
try {
LocalDate ld = LocalDate.of( 2018 , 2 , 31 ) ; // Invalid, February never has 31 days.
return Boolean.TRUE ;
} catch ( DateTimeException e ) {
return Boolean.FALSE ;
}
Leap Year
Yes, LocalDate checks for Leap Year to handle February 29 correctly.
try {
LocalDate ld = LocalDate.of( 2018 , 2 , 29 ) ; // Invalid, as 2018 is a common year.
return Boolean.TRUE ;
} catch ( DateTimeException e ) {
return Boolean.FALSE ;
}
false
…
LocalDate ld = LocalDate.of( 2020 , 2 , 29 ) ; // Valid, as 2020 is a leap year.
…
true
Compare dates
to check if the date is no sooner than the current data
I assume you meant "current date".
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Compare with isBefore, isAfter, and isEqual.
boolean b = ld.isBefore( today ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.