1

I've recently switched to joda time LocalDate from Calendar to avoid timezone issues in my project (I don't need time zone there). At some point I need to get a Timestamp from a LocalDate:

  class DateTimeUtils{
   static Timestamp getDeadline(LocalDate localDate, int daysToAdd){
      localDate = localDate.plusDays(daysToAdd);
      System.out.println(localDate);//This prints 2017-06-02
      return new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());         
   }
  public static void main(String... args){
     LocalDate localDate= new LocalDate(2017,5,31);
     Timestamp timeStamp=getDeadline(localDate,2);
     System.out.println(timeStamp);//This prints 2017-06-01 23:00:00.0
  }
 }

For some reason that I can't figure out, after converting the localdate to timestamp, the result falls back to 23:00 of the previous day. Why is that?

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206
  • your code return the same output in both methods to me (I'm from Brazil) `2017-06-02` and `2017-06-02 00:00:00.0` Maybe the daylight saving of your local make it back to 23:00:00 – Erick Maia May 19 '17 at 13:37
  • 1
    `localDate.toDateTimeAtStartOfDay()` is not avoiding timezone issues. It’s just using the default timezone. You’ll still have issues with your database’s timezone and the timezone your JDBC driver assumes. – VGR May 19 '17 at 13:38
  • @ErickMaia, there's no daylight saving in my local machine.I get 0 when I run this code on my machine: TimeZone timezone = TimeZone.getDefault(); System.out.println("DayLight Saving: " + timezone.getDSTSavings()); – Mikayil Abdullayev May 19 '17 at 13:46
  • 1
    I've just checked it with `java.time.LocalDate`. I don't get that problem with it. Also, if I use `localDate.toDate()` instead of `localDate.toDateTimeAtStartOfDay()`, that also solves the problem. – Mikayil Abdullayev May 19 '17 at 13:50
  • If you can work with dates only and not times, you can avoid time zone issues. Basil Bourque explains in the last two lines of [his answer](http://stackoverflow.com/a/44075323/5772882) how you may save a `LocalDate` directly to your database and hence avoid the use of a timestamp. – Ole V.V. May 21 '17 at 07:49

2 Answers2

3

Have you tried using the new Java 8 Date Time API? It allows easy inter-operability with the legacy classes like java.sql.Timestamp. The following code gives me expected results with JDK 8 java.time classes.

public class DateTimeUtils {
    static Timestamp getDeadline(LocalDate localDate, int daysToAdd) {
        localDate = localDate.plusDays(daysToAdd);
        return Timestamp.valueOf(localDate.atStartOfDay());
    }

    public static void main(String... args) {
        LocalDate localDate = LocalDate.of(2017, 5, 31);
        Timestamp timestamp = getDeadline(localDate, 2);
        System.out.println(timestamp);// This prints 2017-06-02 00:00:00.0
    }
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Pallavi Sonal
  • 3,661
  • 1
  • 15
  • 19
  • I get the same output as you. I don’t get the same timestamp as you since my computer is in a different time zone (the timestamp I get is equal to an instant of 2017-06-01T22:00:00Z since my computer is running Central European Summer Time (Europe/Oslo or Europe/Hamburg) equal to GMT+2). – Ole V.V. May 21 '17 at 07:40
3

Time zone matters

to avoid timezone issues in my project

You cannot ignore time zone issues. Wishful dreaming. Be brave, grab the bull by the horns, and take on the challenge of learning to deal with time zones. Your programming work will be much easier.

In your call to toDateTimeAtStartOfDay, you chose to omit the argument for time zone, the DateTimeZone object. So, at runtime, the JVM’s current default time zone was silently implicitly applied.

Then you convert to a java.sql.Timestamp (apparently – you were not explicit about package) which is always in UTC.

You did not provide your runtime current default time zone, so I cannot be more exact in the details.

Using java.time

The Joda-Time project is now in maintenance mode, with its team advising migration to the java.time classes. Both projects were led by the same man, Stephen Colebourne, so the they share the same conceptual approach. Pretty easy to switch over.

To get today’s date, specify the time zone. For any given moment, the date varies around the globe by zone.

See how we pass the zone to atStartOfDay.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z );
LocalDate twoDaysLater = today.plusDays( 2 ) ;
ZonedDateTime zdt = twoDaysLater.atStartOfDay( z ) ;
Instant instant = zdt.toInstant();  // Instant is always in UTC by definition. 

With JDBC 4.2 and later, you can work directly with the java.time types. Call PreparedStatement.setObject and ResultSet.getObject.


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