-5

I have a GregorianCalendar object. How do I get a formatted string?

The line System.out.print("End of rental: " + endDate); produces the following really long calendar. How can I format this down to dd/mm/yyyy?

End of rental: java.util.GregorianCalendar[time=1495050625200,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2017,MONTH=4,WEEK_OF_YEAR=20,WEEK_OF_MONTH=3,DAY_OF_MONTH=17,DAY_OF_YEAR=137,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=50,SECOND=25,MILLISECOND=200,ZONE_OFFSET=0,DST_OFFSET=3600000]
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Dean McGuigan
  • 21
  • 1
  • 1
  • 1
    you should check the documentation for `java.util.GregorianCalendar` – Bill F May 12 '17 at 20:09
  • 1
    There must be 50 Q/A on date formatting on this site. But check [`DateFormat`](https://docs.oracle.com/javase/8/docs/api/java/text/DateFormat.html) for example. – KevinO May 12 '17 at 20:14
  • @KevinO Actually, I looked for a duplicate Question but could not find one specifically asking how to format a `GregorianCalendar`. So I wrote an Answer. If you can find a duplicate, please mark this Question as a duplicate and I will vote to close along with you. – Basil Bourque May 12 '17 at 23:34
  • @BasilBourque, with all due respect, [Using GregorianCalendar with SimpleDateFormat](http://stackoverflow.com/questions/10829942/using-gregoriancalendar-with-simpledateformat) for example. But whether one uses `SimpleDateFormat`or `DateTimeFormatter`, the basic question is still about formatting a date, which is asked/answer all the time. Nonetheless, your answer is specific to this question. It is the larger problem of the OP, in all likelihood, googling for the *specifics* without understanding the general approach. Note: I'm not a DV. – KevinO May 13 '17 at 02:25
  • @KevinO (A) [That Question](http://stackoverflow.com/q/10829942/642706) is too over-wrought to be considered a duplicate of the very simple question of “I have a GregorianCalendar object, how do I get a formatted string?”. So this Questions still stands as a valid and useful one to keep. I have closed many Questions as duplicates, but only where clear-cut. I am annoyed by the down-votes here by people who have not bothered to cite a duplicate. Yes, it *seemed* like a dup to me too until I bothered to look and found none. (B) What is a “DV” - oh, I get it, "Down-Voter"? – Basil Bourque May 13 '17 at 02:36
  • 1
    Possible duplicate of [Using GregorianCalendar with SimpleDateFormat](http://stackoverflow.com/questions/10829942/using-gregoriancalendar-with-simpledateformat) – Matthias M May 13 '17 at 02:56
  • 1
    @Matthias [That Question](http://stackoverflow.com/q/10829942/642706) is not a duplicate. That question is mainly about parsing a string into a `GregorianCalendar` object whereas **this Question starts with a `GregorianCalendar` object in hand**. To quote: “turn a date string into a GregorianCalendar object”, “ takes in a chuck of text from a file, breaks it down”, “`convertFromDMY`”. – Basil Bourque May 13 '17 at 03:03

2 Answers2

3

tl;dr

endDate.toZonedDateTime()
       .format( DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )

23/01/2017

Details

Convert from the troublesome legacy class of GregorianCalendar to the modern java.time class of ZonedDateTime. Call toString to generate text in standard ISO 8601 format.

endDate.toZonedDateTime().toString()

Get something like this:

2017-01-23T12:34:56.789-07:00[America/Los_Angeles]

For just your date, use DateTimeFormatter. Specify your custom formatting pattern.

endDate.toZonedDateTime()
       .format( DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )

23/01/2017


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?

Table of which java.time library to use with which version of Java or Android

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    Dear Down-Voter: Please leave a criticism along with your vote. – Basil Bourque May 12 '17 at 23:31
  • Hey, I have been playing with `java.time` for long now, had not discovered this conversion yet, between `GregorianCalendar` and `ZonedDateTime`. It’s a natural and good thing to have since those classes match well on intended use. The opposite conversion exists as `GregorianCalendar.from(ZonedDateTime)`. Thanks for the news, no matter if it’s old news. – Ole V.V. May 13 '17 at 05:57
  • @OleV.V. Yes, this conversion avenue is not obvious because the methods live only on the concrete `GregorianCalendar` class but *not* on the commonly-used `Calendar` abstract class. If you have a `Calendar` object in hand you must test with `instanceOf` to verify it is actually a `GregorianCalendar`, cast it, then call the conversion method. – Basil Bourque May 13 '17 at 08:34
2

@Basil Bourque’s answer is highly recommended. I’d just like to supplement it with the answer for Java 6 and 7 (so please ignore if you are on Java 8 or later). Also if you can avoid the Calendar class completely, which is best, you should use that other answer. In the following I am assuming that you cannot avoid getting a Calendar object from some legacy API that you cannot change or don’t want to change just now.

java.time and ThreeTen Backport

I am taking my example from a duplicate question, How to convert a Calendar object to date format that looks like this (link at the bottom). The desired format there was given as

7/23/2019 11:02:11 AM

Which we can obtain in the following way. First we instantiate a formatter:

private static final DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern("M/d/u h:mm:ss a", Locale.ENGLISH);

Then we use it like this

    Calendar cal = getCalendarFromLegacyApi();

    ZonedDateTime zdt = DateTimeUtils.toZonedDateTime(cal);
    String howItShouldLook = zdt.format(formatter);
    System.out.println(howItShouldLook);

Output in this example is the desired:

7/23/2019 11:02:11 AM

Question: Can I use java.time on Java 7?

Yes, java.time works nicely Java 7. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161