FYI, calendaring is not an easy task for new programmer. The job is more tricky and complicated than you might intuit. For one thing, you will need to get very clear on the difference between (a) a date-with-time and (b) a moment, as discussed on What's the difference between Instant and LocalDateTime?.
Never use java.util.Date
. Use only the modern classes found in the java.time package.
For a time-of-day, use LocalTime
.
LocalTime start = LocalTime.of( 16 , 0 ) ;
Display to user by automatically localizing.
Locale locale = Locale.CANADA_FRENCH ; // Or `Locale.US`, `Locale.UK` or such.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM ).withLocale( locale ) ;
String output = start.format( f ) ;
Specify the length of time for the exam slot as a Duration
.
Duration duration = Duration.ofHours( 1 ) ;
Usually best for a scheduling app to store the start and the duration, but not the end. The end can always be calculated.
Calculate the ending time. Adding the duration to a LocalTime
object generates a new and separate LocalTime
object rather than alter the original (immutable objects).
LocalTime end = start.plus( duration ) ;
Beware: Adding a span of time to a LocalTime
ignores the issue of time zone anomalies such as Daylight Saving Time (DST). Better to add the duration to the ZonedDateTime
object seen below.
For date, use LocalDate
.
LocalDate ld = LocalDate.of( 2020 , Month.MARCH , 23 ) ;
Move back in time three weeks by using the Period
class.
Period period = Period.ofWeeks( 3 ) ;
LocalDate examDate = ld.minus( period ) ; // 3 weeks prior.
Combine the date and time-of-day into a LocalDateTime
.
LocalDateTime ldt = LocalDateTime.of( examDate , start ) ;
To determine a moment, a specific point on the timeline, provide the context of a time zone. You get a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtStart = ldt.atZone( z ) ;
Get the ending time.
ZonedDateTime zdtEnd = zdtStart.plus( duration ) ; // Automatically accounts for anomalies such as Daylight Saving Time (DST).
To see that moment in UTC, extract an Instant
.
Instant instant = zdt.toInstant() ;
As for database storage, some databases such as Postgres and H2 have good support for date-time data types. Use a JDBC driver that complies with JDBC 4.2 or later to exchange java.time objects via the setObject
/getObject
methods.
Unfortunately, JDBC 4.2 requires support for OffsetDateTime
but not the more commonly used Instant
and ZonedDateTime
types. No problem really, as we can easily convert back-and-forth.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Tip: For this kind of work you may want to add the ThreeTen-Extra library to your project to access the Interval and/or LocalDateRange
classes. These represent a span-of-time tied to the timeline, as a pair of Instant
objects or LocalDate
objects respectively.
I have been brief here. All this has been covered many many times already on Stack Overflow. Search to learn more.
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
.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
https://i.stack.imgur.com/eKgbN.png
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.