Reputation: 105
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.
Upvotes: 6
Views: 21035
Reputation: 338594
LocalDate.now()
.toString() // Expecting January 23, 2018.
2018-01-23
LocalDate.now()
.plusDays( 10 )
.toString() // Expecting February 2, 2018.
2018-02-02
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.
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 ) ;
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.
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 ) ;
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.
2018
is the year 2018. No math with 1900
. 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?
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.
Upvotes: 2
Reputation: 308763
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.
Upvotes: 6
Reputation: 139931
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.
Upvotes: 9