Reputation: 389
I want to be able to create a calendar of sorts, where each day is composed of time slots. What is the best way to represent this setup in Java? I am parsing the information and I get it as 10:00 and an int 3 where the int represents the hours the event will take.
I want to be able to add events easily, they will never really be deleted, but they will often be looked up.
I took a look at the Java.text.DateFormat in hopes that it could handle my needs but it seems it is mostly for printing the output.
Upvotes: 5
Views: 8166
Reputation: 338256
Avoid the bundled java.util.Date, java.util.Calendar, and java.text.DateFormat/SimpleDateFormat classes. They are notoriously troublesome.
Yes, Joda-Time 2.3 has classes for your needs.
DateTime represents a moment. See Period
, Duration
, and Interval
classes that all relate to spans of time.
A DateTime
represents a moment in time along with a time zone. Unlike a java.util.Date that seems to have a time zone but truly does not, a DateTime really does have a time zone assigned. Almost always best to specify the time zone, otherwise you get the JVM's default time zone.
The ISO 8601 standard defines a textual way to to represent a span of time, called a Duration. Uses this format: PnYnMnDTnHnMnS
. To be more flexible, rather than store an int of 3 for three hours, you might store PT3H
where "P" means Period, "T" means Time-portion, and "3H" means three hours. In Joda-Time, the Period
class takes that string as a constructor and outputs it when calling toString
. So one way to do your calendar is store a DateTime (start) and a ISO string "Duration".
Period period = new Period( "PT3H" );
An alternative common way is to store a duration in milliseconds. This is basically what the Duration
field in Joda-Time does, wraps a milliseconds count.
In Interval
in Joda-Time represents span with a specific DateTime start and a DateTime end. You may not want to store that, but instantiating such objects may have other uses. This class offers handy methods such as "overlap" and containsNow
. If "containsNow" returns true, you know that event in question is now happening.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime startDateTime = new DateTime( 2014, 1, 23, 14, 0, 0, timeZone );
Interval interval = new Interval( startDateTime, period );
Dump to console…
System.out.println( "interval: " + interval );
When run…
interval: 2014-01-23T14:00:00.000+01:00/2014-01-23T17:00:00.000+01:00
Java 8 brings a new java.time.* package of classes defined by JSR 310. These classes were inspired by Joda-Time but are entirely re-architected.
You can use Joda-Time today and continue in Java 8, as the project continues to be maintained actively. Later you learn to transition to the java.time package.
Upvotes: 2
Reputation: 4051
Use the Joda-Time (or wait for the Java 8 where it's successor is implemented). This lib contains powerful parsing options and handy manipulation options as well. If you receive an int with hours the event will take, you can use it to i.e. get the end time.
int hours = (parsed from input);
DateTimeFormatter dtf = DateTimeFormat.forPattern("HH:mm");
LocalTime startTime = dtf.parseLocalTime(stringWithTimeFromUser);
LocalTime endTime = startTime.plusHours(hours);
If you need to convert it to a datetime you can combine the classes as well. I.e. if you have the datetime and just want to change the time to what user has provided, you would:
DateTime dateTime = getItFromSomewhere();
DateTime dateTimeWithNewTime = dateTime.withFields(localTime);
Typically you would get the date from the users as well though ;)
The library has extensive documention, look there.
Upvotes: 5
Reputation: 3634
Use Joda-Time to represent the actual time. Then I'd use PrimeFaces Schedule component (http://www.primefaces.org/showcase/ui/scheduleHome.jsf) for display.
This would mean learning JSF & JPA libraries.
Upvotes: 2