I'm trying to print a few things, such as today's date, the day of the week, the date that it will be 100 days from now, the day of the week one hundred days from now, my birthday and day of the week, and 10,000 days after my birthday and that day of the week. Now, I understand that the GregorianCalendar starts at 0 for January and goes to 11 for December. I get that, so it makes sense that when I attempt to print the date it says today's date is 8/25/12 rather than 9/25/12, but I have no idea how to correct this without setting the date ahead an extra month and then actually putting the month into October rather than September.
Here is what I'm dealing with currently.
GregorianCalendar cal = new GregorianCalendar();
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
int month = cal.get(Calendar.MONTH);
int year = cal.get(Calendar.YEAR);
int weekday = cal.get(Calendar.DAY_OF_WEEK);
cal.add(Calendar.DAY_OF_MONTH, 100);
int dayOfMonth2 = cal.get(Calendar.DAY_OF_MONTH);
int month2 = cal.get(Calendar.MONTH);
int year2 = cal.get(Calendar.YEAR);
int weekday2 = cal.get(Calendar.DAY_OF_WEEK);
GregorianCalendar birthday = new GregorianCalendar(1994, Calendar.JANUARY, 1);
int dayOfMonth3 = birthday.get(Calendar.DAY_OF_MONTH);
int month3 = birthday.get(Calendar.MONTH);
int year3 = birthday.get(Calendar.YEAR);
int weekday3 = birthday.get(Calendar.DAY_OF_WEEK);
birthday.add(Calendar.DAY_OF_MONTH, 10000);
int weekday4 = birthday.get(Calendar.DAY_OF_WEEK);
int dayOfMonth4 = birthday.get(Calendar.DAY_OF_MONTH);
int month4 = birthday.get(Calendar.MONTH);
int year4 = birthday.get(Calendar.YEAR);
System.out.printf("Todays date is " +month + "/" +dayOfMonth +"/" +year +".");
System.out.printf(" It is day " +weekday +" of the week");
System.out.println("");
System.out.printf("In 100 days it will be " +month2 + "/" +dayOfMonth2 +"/" +year2 +". ");
System.out.printf("Day " +weekday2 +" of the week");
System.out.println("");
System.out.printf("My Birthday is " +month3 + "/" +dayOfMonth3 +"/" +year3 +". "+"Day " +weekday3 +" of the week");
System.out.println("");
System.out.printf("10,000 days after my birthday is " +month4 + "/" +dayOfMonth4 +"/" +year4 +". " +"Day " +weekday4 +" of the week");
So I need help correcting the month for today's date, the date in 100 days, the date of my birthday, and 10,000 days after my birthday. Any help or insight is much appreciated.
I get that, so it makes sense that when I attempt to print the date it says today's date is 8/25/12 rather than 9/25/12, but I have no idea how to correct this without setting the date ahead an extra month
If you are going to print the month by doing
int month = cal.get(Calendar.MONTH);
...
System.out.printf("Todays date is " + month + ...
Then you want to print month + 1, not just month.
Ultimately though you are going to save a lot more time and headache by just using SimpleDateFormat for formatting Dates as Strings.
Yes, you need to know that Calendar.JANUARY equals zero. Months are zero-based for Calendar.
You're working far too hard here. You're dealing too much with primitives.
Here's how to print today's date:
DateFormat formatter = new SimpleDateFormat("yyyy-MMM-dd");
formatter.setLenient(false);
Date today = new Date();
System.out.println(formatter.format(today));
Here's how to get 100 days from now:
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.DAY_OF_YEAR, 100);
Date oneHundredDaysFromToday = calendar.getTime();
System.out.println(formatter.format(oneHundredDaysFromToday));
Stop dealing with all those int values.
tl;dr
LocalDate.now()
.toString() // Expecting January 23, 2018.
2018-01-23
LocalDate.now()
.plusDays( 10 )
.toString() // Expecting February 2, 2018.
2018-02-02
Avoid legacy date-time classes
The Calendar and GregorianCalendar classes are confusing, poorly-designed, and troublesome. Avoid these classes and the related old legacy date-time classes. Now supplanted by the java.time classes.
java.time
today's date,
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 ) ;
Day of week
the day of the week,
The DayOfWeek class represents a day-of-week from Monday to Sunday. Pass these objects around your code rather than a mere integer 1-7.
DayOfWeek dow = ld.getDayOfWeek() ;
If you must have a number, get 1-7 for Monday-Sunday per ISO 8601 standard.
int dowNumber = ld.getDayOfWeek().getValue() ; // Number 1-7 for Monday-Sunday.
Adding days
the date that it will be 100 days from now, the day of the week one hundred days from now, my birthday and day of the week, and 10,000 days after my birthday and that day of the week.
Add and subtracting days is simple, using plus… and minus… methods.
LocalDate later = ld.plusDays( 10 ) ; // Ten days later.
Alternatively, use a Period to represent a number of years-months-days.
Period p = Period.ofDays( 10 ) ;
LocalDate later = ld.plus( p ) ;
One hundred days or 10,000 days would be added the same way.
LocalDate later = ld.plusDays( 10_000 ) ;
Numbering
Now, I understand that the GregorianCalendar starts at 0 for January and goes to 11 for December
The java.time classes use sane numbering, unlike the legacy classes.
The number 2018 is the year 2018. No math with 1900.
Months are numbered 1-12 for January-December.
Days of the week are numbered 1-7 for Monday-Sunday, per the ISO 8601 standard.
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.
Related
I want to increase a certain date by 1 day. I create a Calendar object like:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);
Then, for increasing it by 1 day, I can do 2 things :
cal.add(Calendar.DAY_OF_MONTH, 1);
OR
cal.add(Calendar.DAY_OF_YEAR, 1);
There are also other "DAY" constants, but I get the same result using the above 2 methods of increasing the day by 1. In which case will I get different results for the two?
For adding it really makes no difference, but this
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));
prints
28
363
Calendar.add Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules.
Here you have a list of the fields of Calendar that you can add or subtract:
MILLISECOND is the number of milliseconds between 0 and 999
SECOND is the number of seconds between 0 and 59
MINUTE is the number of minutes between 0 and 59
HOUR is the number of hours between 0 and 11
HOUR_OF_DAY is the number of hours between 0 and 23
DAY_OF_WEEK is the day in relation of the week between 1 and 7
DAY_OF_MONTH is the day in relation of the month between 1 and 31
DAY_OF_YEAR is the day in relation of the year between 1 and 366
WEEK_OF_MONTH is the week in relation of the month starting from 1
WEEK_OF_YEAR is the week in relation of the year starting from 1
MONTH is the month in relation of the year between 0 and 11
YEAR is the number of years starting from 1
Hours, days and weeks have multiple fields but it doesn't matter which one you choose1. For example using -8 for DAY_OF_WEEK will work.
calendar.add(Calendar.DAY_OF_MONTH, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_WEEK, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_YEAR, -2); // subtract 2 days
calendar.add(Calendar.YEAR, -2); // subtract 2 years
1It doesn't matter only using Calendar.add, with other operations the results might be different.
Use Calendar.DATE for your purposes. In your case these three constants are synonyms.
It doesn't make any difference when you call add. However the getters return different results :D
code snippet from GregorianCalendar#add
case DAY_OF_MONTH: // synonym of DATE
case DAY_OF_YEAR:
case DAY_OF_WEEK:
break;
DAY_OF_YEAR
Field number for get and set indicating the day number within the current year
DAY_OF_MONTH
Field number for get and set indicating the day of the month. This is a synonym for DATE
You will see difference if the day is greater than 31.
You essentially advance the date by one, in both the cases. So there is no difference in both the approaches.
But sticking to a single method will render consistency across your codebase, maintainers will feel at home and probably the runtime optimizes the method call by compiling it as well.
Actually, there can and will be a difference depending on what field type you choose:
*
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html
Usage model.
To motivate the behavior of add() and roll(), consider a
user interface component with increment and decrement buttons for the
month, day, and year, and an underlying GregorianCalendar. If the
interface reads January 31, 1999 and the user presses the month
increment button, what should it read? If the underlying
implementation uses set(), it might read March 3, 1999. A better
result would be February 28, 1999. Furthermore, if the user presses
the month increment button again, it should read March 31, 1999, not
March 28, 1999. By saving the original date and using either add() or
roll(), depending on whether larger fields should be affected, the
user interface can behave as most users will intuitively expect.
tl;dr
LocalDate.of( 2012 , Month.JANUARY , 31 )
.plusDays( 1 )
2012-02-01
…or…
LocalDate.of( 2012 , 1 , 31 ) // Sane numbering: 1-12 for January-December, and `2012` means year 2012.
.plusDays( 1 )
2012-02-01
java.time
The Calendar class is confusing, awkward, and poorly designed. Among its many problems are these pass-the-units-flag methods. Fortunately, you can now forget all about this class.
The java.time classes built into Java 8 and later now supplant the 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 ) ;
Parts
With a LocalDate in hand, you may interrogate for its parts.
To get the day-of-month, that is, the "date" such as 23 from January 23, 2018:
int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.
To get the nth day of the year, from 1-365, or in a leap year, 1-366:
int dayOfYear = ld.getDayOfYear() ;
Math
Adding or subtracting days is quite simple and intuitive in java.time. Convenience methods and span-of-time objects make the code much more clear.
LocalDate dayLater = ld.plusDays( 1 ) ;
So getting tomorrow would be:
LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;
Alternatively, you can represent a span-of-time unattached to the timeline. For years-months-days, use Period. For hours-minutes-seconds, use Duration.
Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;
Note that java.time uses sane numbering, unlike the legacy classes. The number 2018 is the year 2018. Months are numbered 1-12 for January-December. Days of the week are numbered 1-7 for Monday-Sunday, per the ISO 8601 standard.
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.
In addition of date it does not make any difference whether you use DAY_OF_MONTH or DAY_OF_YEAR. However, it makes sense when you get call getter and pass one of those.
Use DATE or DAY_OF_MONTH both are same
Here is the difference :
DATE or DAY_OF_MONTH : Get and Set indicating the day of the month
DAY_OF_WEEK : get and set indicating the week number within the current month
DAY_OF_YEAR : get and set indicating the day number within the current ye
Source : https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
public static String findDay(int month, int day, int year) {
// Creating a calendar
Calendar calndr = Calendar.getInstance();
calndr.set(Calendar.MONTH, month-1);
calndr.set(Calendar.YEAR, year);
calndr.set(Calendar.DAY_OF_MONTH, day);
String[] strDays = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
return strDays[calndr.get(Calendar.DAY_OF_WEEK)-1].toUpperCase();
}
}
The following code gives the wrong information:
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
public class test {
public static void main(String[] args) {
GregorianCalendar fmt = new GregorianCalendar(2000, 7, 3);
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
String result = df.format(fmt.getTime());
System.out.println("fmt: " + result);
}
}
It outputs:
fmt: 03-Aug-2000
While I need the Month to be July, as I have set the month to 7?
My guess, is that you're expecting the 7th month to be July, but the month value is 0-based, so July would be represented by a 6.
month - the value used to set the MONTH calendar field in the calendar. Month value is 0-based. e.g., 0 for January.
You also probably want to enter the 4-digit date
You'd end up with the following
GregorianCalendar fmt = new GregorianCalendar(1975, 6, 3);
Here's the documentation for GregorianCalendar
As noted by other people, there are two problems in your current code:
Months are zero based. So, month 7 is August, not July =\
Year doesn't start by default at 1900 but at 1970, but if you set the year by yourself you'll get as year the same number you're setting, in this case, 75 (not 1975 as expected).
To solve this, you may create the GregorianCaledar as new GregorianCaledar(1975, 6, 3). Or even better, stop working directly with this class and instead use the abstract class Calendar:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 1975);
calendar.set(Calendar.MONTH, Calendar.JULY);
calendar.set(Calendar.DATE, 3);
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
String result = df.format(calendar.getTime());
System.out.println("fmt: " + result);
Why to use Calendar instead of GregorianCalendar? Because you should always work with abstract class/interface instead of class implementation.
Of course,
You have instantiated the GregorianCalendar to year 75.
What was your purpose?
See the API
http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html
Also pay attention that in GregorianCalendar the month start from 0
Taken from the JavaDoc above:
"month - the value used to set the MONTH calendar field in the calendar. Month value is 0-based. e.g., 0 for January."
In the GregorianCalendar months are marked from 0 (which represents January), and so do the years. So if you want to represent July 3rd, 1975, you should use:
GregorianCalendar fmt = new GregorianCalendar(1975, 6, 3);
tl;dr
LocalDate.of( 2000 , 7 , 3 )
…or…
LocalDate.of( 2000 , Month.JULY , 3 )
java.time
As already noted, the troublesome old GregorianCalendar has crazy numbering schemes with year, month, and day-of-week. Months are numbered 0-11 for January-December, so August is # 7 rather than # 8. Avoid these old legacy classes like the Plague. Instead, use the modern java.time classes.
Te java.time classes use sane numbering:
2014 means the year 2014. No funky math with 1900.
2 means February, 1-12 for January-December.
1 means Monday, 1-7 for Monday-Sunday per [ISO 8601][1] standard.
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( 2000 , 7 , 3 ) ; // Years use sane direct numbering (2014 means year 2014). 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( 2000 , Month.JULY , 3 ) ;
Generate a String in your desired format. Note the Locale argument used to specify the human language and cultural norms to be used in localizing.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ;
String output = ld.format( f ) ;
03-Jul-2000
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 would like to get which day of the week is the current day and looking the SimpleDateFormat class I tought that the "F" is what I need. So I wrote a little test:
System.out.println(new SimpleDateFormat("F").format(new Date()));
Today is wednesday and I expect to get 3 as output. Instead I get 2.
As english isn't my mothertongue, did I missunderstand the meaning of the format?
F - Day of week in month
E - Day name in week
try u - Day number of week (1 = Monday, ..., 7 = Sunday)
Note that 'u' is since Java 7, but if you need just day number of the week then use Calendar
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_WEEK));
You can change first day of week by changing Locale or directly as
c.setFirstDayOfWeek(Calendar.SUNDAY);
Today is the second Wednesday in the current month.
The java.util.Calendar/.Date and related classes are a confusing mess as you have learned the hard way. Counting from zero for month numbers and day-of-week numbers is one of many poor design choices made in those old classes.
java.time
Those old classes have been supplanted in Java 8 and later by the java.time framework. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
DayOfWeek
For day of week, use the well-named DayOfWeek enum.
If you want an integer for day-of-week compliant with ISO 8601 where Monday = 1 and Sunday = 7, you can extract that from an instance of DayOfWeek.
Conversion
If starting with a java.util.Calendar object, convert to java.time.
An Instant is a moment on the timeline in UTC.
Instant instant = myJavaUtilCalendarObject.toInstant();
Apply a time zone in order to get a date in order to get a day-of-week.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
DayOfWeek dayOfWeek = zdt.getDayOfWeek();
Note that time zone in crucial in determining a date, and therefore a day-of-week. The date is not the same around the world simultaneously. A new day dawns earlier in Paris than in Montréal, for example.
Number Of Day-Of-Week
Now that we have java.time and this enum built into Java, I suggest you freely pass around those enum instances rather than a magic number.
But if you insist on an integer, ask the DayOfWeek.
int dayOfWeekNumber = dayOfWeek.getValue();
String Of Day-Of-Week
That enum generates a localized String for the name of the day-of-week.
String output = dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.ENGLISH.
Indexes for the days of week start from 0, not 1.
F -> Day of week in month(1-5)
Today is - 09/01/2013(dd/MM/yyyy) which fall 2nd in week so it has printed 2.
If you try with 16/01/2013 then it would print 3.
F = Day of Week in Month
1day to 7day, it will print 1.
8day to 14day, it will print 2.
15day to 21day, it will print 3.
22day to 28day, it will print 4 and
29day to 31day, it will print 5.
just use this method for this.
public String day(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("EEEEEEEEE", new Locale("tr", "TR"));
return sdf.format(date);
}
I want to increase a certain date by 1 day. I create a Calendar object like:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);
Then, for increasing it by 1 day, I can do 2 things :
cal.add(Calendar.DAY_OF_MONTH, 1);
OR
cal.add(Calendar.DAY_OF_YEAR, 1);
There are also other "DAY" constants, but I get the same result using the above 2 methods of increasing the day by 1. In which case will I get different results for the two?
For adding it really makes no difference, but this
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));
prints
28
363
Calendar.add Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules.
Here you have a list of the fields of Calendar that you can add or subtract:
MILLISECOND is the number of milliseconds between 0 and 999
SECOND is the number of seconds between 0 and 59
MINUTE is the number of minutes between 0 and 59
HOUR is the number of hours between 0 and 11
HOUR_OF_DAY is the number of hours between 0 and 23
DAY_OF_WEEK is the day in relation of the week between 1 and 7
DAY_OF_MONTH is the day in relation of the month between 1 and 31
DAY_OF_YEAR is the day in relation of the year between 1 and 366
WEEK_OF_MONTH is the week in relation of the month starting from 1
WEEK_OF_YEAR is the week in relation of the year starting from 1
MONTH is the month in relation of the year between 0 and 11
YEAR is the number of years starting from 1
Hours, days and weeks have multiple fields but it doesn't matter which one you choose1. For example using -8 for DAY_OF_WEEK will work.
calendar.add(Calendar.DAY_OF_MONTH, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_WEEK, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_YEAR, -2); // subtract 2 days
calendar.add(Calendar.YEAR, -2); // subtract 2 years
1It doesn't matter only using Calendar.add, with other operations the results might be different.
Use Calendar.DATE for your purposes. In your case these three constants are synonyms.
It doesn't make any difference when you call add. However the getters return different results :D
code snippet from GregorianCalendar#add
case DAY_OF_MONTH: // synonym of DATE
case DAY_OF_YEAR:
case DAY_OF_WEEK:
break;
DAY_OF_YEAR
Field number for get and set indicating the day number within the current year
DAY_OF_MONTH
Field number for get and set indicating the day of the month. This is a synonym for DATE
You will see difference if the day is greater than 31.
You essentially advance the date by one, in both the cases. So there is no difference in both the approaches.
But sticking to a single method will render consistency across your codebase, maintainers will feel at home and probably the runtime optimizes the method call by compiling it as well.
Actually, there can and will be a difference depending on what field type you choose:
*
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html
Usage model.
To motivate the behavior of add() and roll(), consider a
user interface component with increment and decrement buttons for the
month, day, and year, and an underlying GregorianCalendar. If the
interface reads January 31, 1999 and the user presses the month
increment button, what should it read? If the underlying
implementation uses set(), it might read March 3, 1999. A better
result would be February 28, 1999. Furthermore, if the user presses
the month increment button again, it should read March 31, 1999, not
March 28, 1999. By saving the original date and using either add() or
roll(), depending on whether larger fields should be affected, the
user interface can behave as most users will intuitively expect.
tl;dr
LocalDate.of( 2012 , Month.JANUARY , 31 )
.plusDays( 1 )
2012-02-01
…or…
LocalDate.of( 2012 , 1 , 31 ) // Sane numbering: 1-12 for January-December, and `2012` means year 2012.
.plusDays( 1 )
2012-02-01
java.time
The Calendar class is confusing, awkward, and poorly designed. Among its many problems are these pass-the-units-flag methods. Fortunately, you can now forget all about this class.
The java.time classes built into Java 8 and later now supplant the 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 ) ;
Parts
With a LocalDate in hand, you may interrogate for its parts.
To get the day-of-month, that is, the "date" such as 23 from January 23, 2018:
int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.
To get the nth day of the year, from 1-365, or in a leap year, 1-366:
int dayOfYear = ld.getDayOfYear() ;
Math
Adding or subtracting days is quite simple and intuitive in java.time. Convenience methods and span-of-time objects make the code much more clear.
LocalDate dayLater = ld.plusDays( 1 ) ;
So getting tomorrow would be:
LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;
Alternatively, you can represent a span-of-time unattached to the timeline. For years-months-days, use Period. For hours-minutes-seconds, use Duration.
Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;
Note that java.time uses sane numbering, unlike the legacy classes. The number 2018 is the year 2018. Months are numbered 1-12 for January-December. Days of the week are numbered 1-7 for Monday-Sunday, per the ISO 8601 standard.
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.
In addition of date it does not make any difference whether you use DAY_OF_MONTH or DAY_OF_YEAR. However, it makes sense when you get call getter and pass one of those.
Use DATE or DAY_OF_MONTH both are same
Here is the difference :
DATE or DAY_OF_MONTH : Get and Set indicating the day of the month
DAY_OF_WEEK : get and set indicating the week number within the current month
DAY_OF_YEAR : get and set indicating the day number within the current ye
Source : https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
public static String findDay(int month, int day, int year) {
// Creating a calendar
Calendar calndr = Calendar.getInstance();
calndr.set(Calendar.MONTH, month-1);
calndr.set(Calendar.YEAR, year);
calndr.set(Calendar.DAY_OF_MONTH, day);
String[] strDays = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
return strDays[calndr.get(Calendar.DAY_OF_WEEK)-1].toUpperCase();
}
}
Right now is 3/15/11 and when I'm calling a new date object:
Date now = new Date();
I'm getting in return
the month as 2 (getMonth()),
the day as 2 (getDay())
and the year (getYear()) as 111.
Is there a reason for this convention?
Straight from the class's documentation:
A year y is represented by the integer y - 1900.
A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.
A date (day of month) is represented by an integer from 1 to 31 in the usual manner.
And as for getDay():
Returns the day of the week represented by this date. The returned value (0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday) represents the day of the week that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.
March 15th 2011 is in fact a Tuesday.
Is there a reason for this convention?
The reason is that it is what the javadoc for Date specifies; see #matt b's answer.
The Date APIs were created in the days of JDK 1.0, and are well known to be problematic in a number of areas. That is why most of the Date methods are marked as Deprecated. (By the way, that means that it is recommended that you don't use them in new code!!)
The Calendar APIs are a significant improvement on Date, but the best by far APIs for handling date / time values in Java are the 3rd-party Joda time APIs.
If you want examples of Joda time usage, look at the link above. There's an example of Calendar usage in the GregorianCalendar javadocs. More examples of Calendar usage may be found on this page.
tl;dr
LocalDate // Modern class to represent a date-only value, without time-of-day, without time zone or offset-from-UTC.
.now( ZoneId.of( "Africa/Tunis" ) ) // Capture the current date as seen in the wall-clock time used by the people of a specific region (a time zone).
.getYear() // Get year number, such as 2019 presently.
…and:
.getMonthValue() // Get month number, 1-12 for January-December.
…and:
.getDayOfMonth() // Get day-of-month number, 1-31.
Details
Apparently you are using either of two terrible date-time classes, java.util.Date or java.sql.Date. Both are outmoded as of the adoption of JSR 310, defining their replacement, the modern 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. If critical, confirm the zone with your user.
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( 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. Ditto for Year & YearMonth.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Accessing parts of a date
The java.time classes use sane numbering, 1-12 for months, 1-7 for days of the week, the year number such as 2019 is the year 2019, and such.
int year = ld.getYear() ; // The year, such as 2019 presently.
int monthNumber = ld.getMonthValue() ; // Number of the month 1-12 for January-December.
Month month = ld.getMonth() ; // Get the `Month` enum object, one of a dozen predefined objects (one for each month of the year).
int dayOfMonth = ld.getDayOfMonth() ; // Get the day of the month, 1-31.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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.