How-To: Get human-friendly dates in Java using the Calendar class

ISO-8601 has a PosseAs part of the groundwork for some upcoming Java shenanigans I’ve finished off reading/skimming Head First Java – and it’s a truly excellent book. I wish it covered Connector/J & MySQL, but I can find that knowledge elsewhere so it’s not that big of a deal.

As part of today’s prep I ended up writing something I didn’t think I’d have to – a function to get a nice, human-readable date as a String. I don’t like having to write things like this because surely getting a nice, human-readable version of what’s essentially a timestamp (if the Date class wasn’t deprecated) has been solved. By which I mean that it’s done – let’s never, ever solve that same problem again. But the issue is that if you don’t know where to look for the solution, then it can take you longer to find it than to solve the problem again, and I think that’s what’s happened to me today when I didn’t feel like learning and using the joda-time API to do something I felt core Java should be capable of.

Before we get to the source code I’d just like to direct a quick word to to the Java API Calendar class developers to say:

  • I don’t care who you worship – the first day of the week is Monday, please see ISO-8601, and
  • Chopping and changing between zero-based constants and one-based constants sucks massive d*cks.

Anyways, the getFriendlyDate function gets a day/month/year from a Calendar object and converts it into something a human being might like to read, like this…

And the source code to perform this scandalous transformation is:

Update 13-Oct-2011: Just realised that the 1st, 2nd, 3rd etc. stuff is broken because I’m checking the last digit in the day of month and using that, so if it ends with 3 I give the suffix “rd” making it “3rd”, which is fine until you get to the 13th, which comes out as “13rd”… I don’t have time to fix it up right now, but I will in the near future. Or do a total re-write using the mighty Shetboy’s formatting advice (see comments).

Cheers!

17 thoughts on “How-To: Get human-friendly dates in Java using the Calendar class”

  1. Your solution is a little too fixed and doesn’t adhere to international (i18n) conventions. It maybe better to use one of the following because they’ve been tested MUCH more than your class definition and will be far less likely to introduce a bug.

    An alternative is to use formatters as shown here

    Joda also has formatters. Both Joda and the standard Java API formatters have almost anything you can think of defined. Joda also supports ISO8601

    And Joda is not that hard to learn, a simple example class I just knocked up for converting between date/string or string/date is pasted below. (please format as you deem best as I forgot how to do that). Note that you can change the DateFormatter definition string to whatever you wish, or pass in the string pattern as a parameter, or even a defined DateFormatter object to these methods to make them even more generic and reusable. And yes, I dislike the method names but I used them to help clarify what they do.

    Note that my formatter example is defined for things like 04-OCT-2011 but all you have to do is change the definition of that formatter line.

    Hope this helps

  2. Thanks for the heads up – that’s a far, far better solution than anything I would have came up with, and good links too. You, sir, are a star! =D

    But I went to the effort of making an ISO-8601 has a posse image AND made a massive d*cks joke, so there!

    Rematch? You lose again! =P LoLz

  3. ha.. ok I submit to your victory.

    This will also save you a lot of problems down the road…
    Strings are IMMUTABLE. Once set they cannot be changed.
    Say for example I have a 1k string and I want to add 1 character to it, what happens is that the original 1k string gets copied to a completely new string with the extra character. So now the memory contains just over 2k of strings until the garbage collector cleans up the unused and de-referenced strings.

    Your code is creating new strings and moving object references from the old string to the new string all over the place in your example.

    So what’s the solution? Use StringBuffer, or its newer cousin StringBuilder. They are virtually the same in how they’re used. The serialize method example shows how to do this.

    Sorry to rip on your code so much; I made exactly the same mistakes too, I just want to help you avoid the pitfalls more quickly than I resolved myself.

    1. Your input is very much appreciated, mate – I’m learning stuff, and at a fair old lick, too!

      I thought that because I’m not using the new keyword at any point, any instance variables are placed on the stack, and get thrown away as soon as the method completes – no garbage collection necessary.

      I believe you’re right in that String concatenation (+= style) uses copy-by-value instead of copy-by-reference (which I assume StringBuffer or StringBuilder is capable of), but as above, no heap usage so method’s stack container gets instantly deallocated on completion of the method and we get the memory back, like, BAAAAM! =D

      That was my take on the memory management side of things from Head First Java, but it wouldn’t surprise me in the least if I’d got it a bit wrong.

  4. And another suggestion. Where you have…

    …consider using your apps own exceptions…

    or,

    Because an invalid date would be an error in most cases. Depends on the app though.

    Note that InvalidDayValueWithinDate is defined by the app writer like…

    // surely this must be a thread record now :)

  5. Thread record broken! Crown rightfully provided! =D

    I didn’t put any exception code in because I was planning to get the date from a JCalendar “date picker”, so it should be pretty impossible to provide bad values and cause the conversion to fail.

    Good point & well made tho. Also, what’s with the serialVersionUID?

    1. The class extends the Exception class, which implements the Serializable interface.

      The use of this identifier is explained within this howto for Implementing Serializable.

      Only implement Serializable when you have to!

      Eclipse gives you a right-click option to resolve the compiler warning/issue, it basically auto-generates the code and unique number.

    1. Um, I don’t think you’ve broken anything.. I reformated your post a little to add the <pre lang=”java”> and </pre> tags, but that’s it – it is as you entered it, or at least as the site saw it.

      There’s currently 85 comments on this post and it’s working just fine, 8 post max? Non! =P

    2. Ah – just figured it out: We were talking about diff posts.

      I thought you meant the one with code in it, but you meant the one that I hadn’t seen which had tripedp the spam filter – so the “The class extends the Exception class” comment was held for moderation.

      Just approved it and deleted the dupe!

      Normal service resumes!

  6. Hey guys, below what I ended up using. It conforms a little bit more to our groups standards, and its got a more general purpose method for getting the suffix on a number.

    I hope your formatting parser picks this up!

Leave a Reply

Your email address will not be published.