user1696162
user1696162

Reputation: 105

Printing the correct date with Java GregorianCalendar Class

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

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 338594

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?

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

duffymo
duffymo

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

matt b
matt b

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

Related Questions