Is there a simple or elegant way to grab only the time of day (hours/minutes/seconds/milliseconds) part of a Java Date (or Calendar, it really doesn't matter to me)? I'm looking for a nice way to separately consider the date (year/month/day) and the time-of-day parts, but as far as I can tell, I'm stuck with accessing each field separately.

I know I could write my own method to individually grab the fields I'm interested, but I'd be doing it as a static utility method, which is ugly. Also, I know that Date and Calendar objects have millisecond precision, but I don't see a way to access the milliseconds component in either case.

Edit: I wasn't clear about this: using one of the Date::getTime() or Calendar::getTimeInMillis is not terribly useful to me, since those return the number of milliseconds since the epoch (represented by that Date or Calendar), which does not actually separate the time of day from the rest of the information.

@Jherico's answer is the closest thing, I think, but definitely is something I'd still have to roll into a method I write myself. It's not exactly what I'm going for, since it still includes hours, minutes, and seconds in the returned millisecond value - though I could probably make it work for my purposes.

I still think of each component as separate, although of course, they're not. You can write a time as the number of milliseconds since an arbitrary reference date, or you could write the exact same time as year/month/day hours:minutes:seconds.milliseconds.

This is not for display purposes. I know how to use a DateFormat to make pretty date strings.

Edit 2: My original question arose from a small set of utility functions I found myself writing - for instance:

Checking whether two Dates represent a date-time on the same day;

Checking whether a date is within a range specified by two other dates, but sometimes checking inclusively, and sometimes not, depending on the time component.

Does Joda Time have this type of functionality?

Edit 3: @Jon's question regarding my second requirement, just to clarify: The second requirement is a result of using my Dates to sometimes represent entire days - where the time component doesn't matter at all - and sometimes represent a date-time (which is, IMO, the most accurate word for something that contains year/month/dayandhours:minutes:seconds:...).

When a Date represents an entire day, its time parts are zero (e.g. the Date's "time component" is midnight) but the semantics dictate that the range check is done inclusively on the end date. Because I just leave this check up to Date::before and Date::after, I have to add 1 day to the end date - hence the special-casing for when the time-of-day component of a Date is zero.

From doc: System.currentTimeMillis() Returns the current time in milliseconds.
–
ATorrasSep 1 '09 at 16:11

Joda would certainly make the first of those easy. I'm not sure I understand the second requirement.
–
Jon SkeetSep 1 '09 at 16:39

wrt Edit 2: Joda has the concept of an Interval which can test whether a date is contained or before/after, etc. It also allows for intuitive manipulation of its DateTime objects so that you can easily test for 'date-time on the same day.'
–
akfSep 1 '09 at 17:07

2

I can only dream of how much easier it would be to work with dates and times if everything was in a common base (pref. 2, 10, or 16), and the entire world was a single time zone. :P
–
Matt BallSep 1 '09 at 18:27

This answer assumes that a day has 24* 60 * 60 seconds. You would be surprise to learn that it's not always the case! The reason is due to the rotation period of Earth, which is slowing down (very very slowly!) along the centuries. Astronomical measurements require adjustments on our clocks. For example, in 30/June/2015 it was added one second to that day. Between 1972 and 2012, a leap second has been inserted about every 18 months, on average. en.wikipedia.org/wiki/Leap_second
–
Richard GomesJul 10 at 9:15

Okay, I know this is a predictable answer, but... use Joda Time. That has separate representations for "a date", "an instant", "a time of day" etc. It's a richer API and a generally saner one than the built-in classes, IMO.

If this is the only bit of date/time manipulation you're interested in then it may be overkill... but if you're using the built-in date/time API for anything significant, I'd strongly recommend that you move away from it to Joda as soon as you possibly can.

As an aside, you should consider what time zone you're interested in. A Calendar has an associated time zone, but a Date doesn't (it just represents an instant in time, measured in milliseconds from the Unix epoch).

Actually, I've never heard of Joda Time (or looked for something that would have brought it up). I'm not sure about using a new time library, since a lot of this project's code is already based on Java Dates and Calendars. I agree that they're both pretty wretched APIs, though. Maybe on the next project...
–
Matt BallSep 1 '09 at 16:28

3

+1 for this as the Java date/time API gets my vote for the single worst API and implementation in the JDK. I'm sure all us Java developers remember our first impression when we asked ourselves, "so how do I do date/time stuff in Java?" and then looked at the Javadoc...
–
SteveDSep 1 '09 at 16:33

Yup, and you can create a DateTime easily from a java.util.Date (or its millis value; I forget which offhand). Joda (mostly) forces you to work out what concept you're really interested in, as well as handling things like time zones more appropriately.
–
Jon SkeetSep 1 '09 at 16:41

You can call the getTimeInMillis() function on a Calendar object to get the time in milliseconds. You can call get(Calendar.MILLISECOND) on a calendar object to get the milliseconds of the second. If you want to display the time from a Date or Calendar object, use the DateFormat class. Example: DateFormat.getTimeInstance().format(now). There is also a SimpleDateFormat class that you can use.

As for comparing dates only while effectively ignoring time, in Joda-Time call the withTimeAtStartOfDay() method on each DateTime instance to set an identical time value. Here is some example code using Joda-Time 2.3, similar to what I posted on another answer today.

If all you're worried about is getting it into a String for display or saving, then just create a SimpleDateFormat that only displays the time portion, like new SimpleDateFormat("HH:mm:ss"). The date is still in the Date object, of course, but you don't care.

If you want to do arithmetic on it, like take two Date objects and find how many seconds apart they are while ignoring the date portion, so that "2009-09-01 11:00:00" minus "1941-12-07 09:00:00" equals 2 hours, then I think you need to use a solution like Jherico's: get the long time and take it module 1 day.

Why do you want to separate them? If you mean to do any arithmetic with the time portion, you will quickly get into trouble. If you pull out 11:59pm and add a minute, now that your time and day are separate, you've screwed yourself--you'll have an invalid time and an incorrect date.

If you just want to display them, then applying various simple date format's should get you exactly what you want.

If you want to manipulate the date, I suggest you get the long values and base everything off of that. At any point you can take that long and apply a format to get the minutes/hours/seconds to display pretty easily.

But I'm just a little concerned with the concept of manipulating day and time separately, seems like opening a can o' worms. (Not to even mention time zone problems!).

Find below a solution which employs Joda Time and supports time zones.
So, you will obtain date and time (into currentDate and currentTime) in the currently configured timezone in the JVM.

Please notice that Joda Time does not support leap seconds. So, you can be some 26 or 27 seconds off the true value. This probably will only be solved in the next 50 years, when the accumulated error will be closer to 1 min and people will start to care about it.

Any idea if the java.time classes (introduced in Java 8) account for leap seconds?
–
Matt BallJul 10 at 15:45

The new java.time framework makes a provision for smearing the Leap Second over the last thousand seconds of the day. See the JavaDoc. But that only applies to a JVM implementation that observes the L.S. None of the current conventional implementations such as OpenJDK or Oracle Java observe the L.S; I don't know about the Real-Time Java implementations, they might.
–
Basil BourqueJul 10 at 16:51