0

I have a dates stored in mysql with no timezone, like 2001-01-10 00:00:00. I have tomcat running in timezone +10:00 for example. I need to generate a Date() that have no offset int the object.

If I do this:

 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
 cal.setTime( new Date(/*from 2001-01-10 00:00:00*/) );
 cal.set(Calendar.HOUR_OF_DAY, 0);
 cal.set(Calendar.MINUTE, 0);
 cal.set(Calendar.SECOND, 0);
 cal.set(Calendar.MILLISECOND, 0);
 Date newDate = cal.getTime();

The result Date object still having the zoneinfo and zoneoffset reporting to server timezone, not UTC.

I need to generate a Date() Object that have ZERO TIME, but mantain the date stored in mysql, independent of tomcat timezone. In other words, I want to generate date with zero hour/min/sec independent of server timezone.

The date generated shows 2001-01-01T00:00:00.000+1400
the time is zero but offset is +14:00.
I want to generate 2001-01-01T00:00:00.000+0000

The mysql datatime is DATETIME

Leonardo
  • 159
  • 1
  • 15
  • 2
    Please read https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/ - a `java.util.Date` is *just* an instant in time. It has no time zone information. – Jon Skeet Nov 17 '17 at 11:16
  • Any reason why you are still hanging on to the outdated classes `Date` and `Calendar`? `java.time`, the modern Java date and time API, is much nocer to work with, and fetching your date-times as `LocalDateTime` from the database should be straightforward. – Ole V.V. Nov 17 '17 at 11:26
  • What is the exact datatype in MySQL? `DATE`? `DATETIME`? – Ole V.V. Nov 17 '17 at 11:28
  • I use Joda too, the problem is that rest holder have a Date property, when a set this date to new Date( from joda zero based time ), the java put the offset in the new Date() object, The server offset, I need to set the offset to zero, like 2001-01-01T00:00:00.000+0000, but allways i get 2001-01-01T00:00:00.000+1400 or +xx00, follow the tomcat timezone – Leonardo Nov 17 '17 at 11:30
  • The mysql data type is DATETIME – Leonardo Nov 17 '17 at 11:31
  • You may also want to look at (the last half of) [my answer here](https://stackoverflow.com/a/47312421/5772882) (“What went wrong”). With the information from your debugger I still claim that it is correct what I wrote there. – Ole V.V. Nov 17 '17 at 13:14

3 Answers3

1

The Date object does not keep timezone information, imagine it as a class with only a long property which stores the number of milliseconds that passed from 1970.

The SimpleDateFormat class or other libraries like JODA are responsible of keeping track of timezone when they transform the date to string.

Zoltan Ersek
  • 755
  • 9
  • 28
  • Hello Zoltan, you are wrong, if you debug and look into java Date Object, you see the zoneinfo corresponding to the server timezone not to the UTC setted in calendar create. The result date is like 2001-01-01T00:00:00.000+1400, the +1400 is the offset that I need to avoid. – Leonardo Nov 17 '17 at 11:19
  • 1
    That is only the result of the toString() method which uses other objects to print the date in the default Locale and Timezone. If you look at the toString() implementation(which the debugger uses to show the value) you will see that other objects are created to make the conversion to string possible. – Zoltan Ersek Nov 17 '17 at 11:31
  • Looking at a random `Date` in my debugger it has fields `cdate` (`null`) and `fastTime` (milliseconds since the eopch if I’m not mistaken). No time zone or offset whatsoever. – Ole V.V. Nov 17 '17 at 11:32
  • 1
    Well, in my java.util.Date() object, I see these fields: fastTime, cdate{..., year, month, hours, minutes,seconds, millis, zoneinfo, zoneOffset.. etc}, where zoneinfo and zoneOffset corresponding to tomcat zone not UTC zero based, this offset cause a wrong date, I need to set offset to zero, like time – Leonardo Nov 17 '17 at 11:40
  • 1
    If you have Joda in your base project, try the follow and look at java Date object. LocalDateTime lt0 = new LocalDateTime(); Date newDtNasc = lt0.toDate(); – Leonardo Nov 17 '17 at 11:45
0

The date itself doesn't have any time zone. Its toString() method uses the current default time zone to return a String representing this date, as explained in this post. However, you can precise the target timezone during the formatting, to obtain the desired result:

// 2001-01-01T00:00:00.000+00:00
long timestamp = 978307200_000L;
Date newDate = new Date(timestamp);

SimpleDateFormat u = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
u.setTimeZone(TimeZone.getTimeZone("UTC"));

SimpleDateFormat k = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
k.setTimeZone(TimeZone.getTimeZone("Pacific/Kiritimati"));

assertEquals("2001-01-01T00:00:00.000+0000", u.format(newDate));
assertEquals("2001-01-01T14:00:00.000+1400", k.format(newDate));
Mincong Huang
  • 5,284
  • 8
  • 39
  • 62
0

Well, the only way that I can acquire desired result, is making an adjust to Java Date, I get the current offset of Tomcat and add/remove him from the Date, the follow function make the date returned by rest is allways the same, independent of the tomcat timezone. I use JODA DateTime for this.

    public Date adjustDateTimeZoneToUTC( Date date )
{
    Date utcDate = null;
    if( date != null )
    {
        int curOffset = TimeZone.getDefault().getRawOffset();

        DateTime dt = new DateTime(date).withZoneRetainFields(DateTimeZone.UTC);
        // Se o offset for NEGATIVO(-12:00), deve-se somar esse tempo
        // Se o offset for POSITIVO(+12:00), deve-se subtrair esse tempo
        if( curOffset >= 0 ) {
            dt.minusMillis(curOffset);
        } else {
            curOffset *= -1;
            dt.plusMillis(curOffset);
        }
        utcDate = dt.toDate();
    }
    return utcDate;
}

On the client side, using angular datepicker or other javascript calendar, you need to do the same way on javascript, for you date stay imutable on different timezones. Like the sample:

$dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {
if (!date) {
    return null;
}
// Right now, only 'UTC' is supported.
if (timezone && timezone === 'UTC') {
    date = new Date(date.getTime());
    date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());
}
return date;

};

Leonardo
  • 159
  • 1
  • 15