1

My class has 2 properties that make up its date:

java.util.Date date;
String timeZone;

How can I see if this date is before the current time on the server?

Basically I want to write something like this, but take timeZone into account:

return date.before(new Date());
TomahawkPhant
  • 1,130
  • 4
  • 15
  • 33
  • `Date` stores internally as UTC, so your `timeZone` variable is not necessary and confusing. – Steve Kuo Feb 06 '13 at 01:21
  • The `timeZone` is the time zone of the user that created the date. – TomahawkPhant Feb 06 '13 at 01:23
  • How are you constructing your `Date`? – Steve Kuo Feb 06 '13 at 01:23
  • Its sent from an html form and then saved in the DB. – TomahawkPhant Feb 06 '13 at 01:24
  • 1
    This question was answered previously: http://stackoverflow.com/questions/2911924/struggling-with-how-to-compare-hours-with-different-time-zones-in-java – Dino Octavian Feb 06 '13 at 01:27
  • That doesn't really answer this question. – TomahawkPhant Feb 06 '13 at 03:26
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Sep 04 '18 at 04:17

3 Answers3

3

Date stores internally as UTC, so your timeZone variable is not necessary. You can simply use Date.before(Date).

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
0
    Calendar startCalendar = Calendar.getInstance();
    int startTimeZoneOffset = TimeZone.getTimeZone(timeZone).getOffset(startDate.getTime()) / 1000 / 60;
    startCalendar.setTime(startDate);
    startCalendar.add(Calendar.MINUTE, startTimeZoneOffset);

    Calendar nowCalendar = Calendar.getInstance();
    int nowTimeZoneOffset = nowCalendar.getTimeZone().getOffset(new Date().getTime()) / 1000 / 60;
    nowCalendar.setTime(new Date());
    nowCalendar.add(Calendar.MINUTE, nowTimeZoneOffset);

    return startCalendar.before(nowCalendar);
TomahawkPhant
  • 1,130
  • 4
  • 15
  • 33
0

tl;dr

Use Instant class, which is always in UTC. So time zone becomes a non-issue.

someInstant.isBefore( Instant.now() )

java.time

The modern approach uses the java.time classes that supplanted the terrible Date & Calendar classes.

As the correct Answer by Kuo stated, your java.util.Date is recording a moment in UTC. So no need for a time zone.

Likewise, its replacement, the java.time.Instant class, also records a moment in UTC. So no time zone needed.

Instant instant = Instant.now() ;  // Capture current in UTC. 

So all you need as member variables on your class is Instant.

public class Event {
    Instant when ;
    …
}

To compare Instant objects, use the isAfter, isBefore, and equals methods.

someInstant.isBefore( Instant.now() ) 

For presentation in a time zone expected by the user, assign a ZoneId to get a ZonedDateTime object. The Instant and the ZonedDateTime both represent the same moment, the same point on the timeline, but viewed through different wall-clock time.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;     // Same moment, different wall-clock time.
String output = zdt.toString() ;              // Generate text in standard ISO 8601 format, wisely extended to append the name of the zone in square brackets.

Or let java.time automatically localize output. To localize, specify:

  • FormatStyle to determine how long or abbreviated should the string be.
  • Locale to determine:
    • The human language for translation of name of day, name of month, and such.
    • The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

Example:

Locale l = Locale.CANADA_FRENCH ;   // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
                                       .withLocale( l );
String output = zdt.format( f );

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.

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.

Where to obtain the java.time classes?

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