0

I have this code below:

Date now = CalendarUtils.getCalendar(getDefaultTimeZone())
                .getTime();

The CalendarUtils class has the below methods

public static Calendar getCalendar(final TimeZone tz) {
    return getCalendar(CalendarUtils.getDate(), tz);
}

public static Calendar getCalendar(final Date time, final TimeZone tz) {
    final GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTimeZone(tz);
    calendar.setTime(time);
    return calendar;
}

public static Date getDate() {
    return CalendarUtils.getDate(System.currentTimeMillis());
}

Where the getDefaultTimeZone() returns a timezone object in a specific timezone. Let's say Europe/Madrid.

However my application is running on a server in Rome.

The problem is that the code above is used to get the local time of Madrid. So at 12:30 am in Rome on Aug. 8th it is still 11:30 pm Aug. 7th in Madrid.

When I use

Date startOfDay = DateUtils.truncate(now, Calendar.DATE);

I would expect Aug. 7th 00:00:00 instead I get Aug 8th 00:00:00

I have read how Date returns the Millis from the Epoch but I would expect that it would return the millis from the Epoch of the date I ask from the Calendar.

When I use the query below at 12:30 am Aug 8th Rome time utilizing the two dates (now and startOfDay) I get results for the 8th of Aug instead the 7th (which is the local time in Madrid).

 public BigInteger getSumForDates(Date fromDate, Date toDate) {

    Session session = sessionFactory.openSession();
    BigInteger sum;
    try{
        sum = (BigInteger)session
            .createSQLQuery(
                    "SELECT SUM(column) FROM table 
                     WHERE (column2 at time zone vas_tz()) >=:fromDate 
                   AND (column2 at time zone vas_tz()) < :toDate")
                  .setTimestamp("fromDate", fromDate)
                  .setTimestamp("toDate", toDate).uniqueResult();
    }catch (final HibernateException e){
        LOGGER.error(e.getMessage());
        throw new ProjectRuntimeException();
    }finally{
        session.close();

    }

EDIT

The DateUtils is the one from package org.apache.commons.lang.time;

public static Date truncate(Date date, int field) {
    if (date == null) {
        throw new IllegalArgumentException("The date must not be null");
    }
    Calendar gval = Calendar.getInstance();
    gval.setTime(date);
    modify(gval, field, MODIFY_TRUNCATE);
    return gval.getTime();
}

When I say to return the millis for the date I have asked the Calendar for, I meant that if the calendar has supplied Aug 7th 11:30 pm (since I provided a timezone) then I would expect the millis from the Epoch until Aug 7th 11:30 adjusted for that timezone. Is this an incorrect expectation?

idipous
  • 2,868
  • 3
  • 30
  • 45
  • possible duplicate of [Java Calendar: getting time for the timezone](http://stackoverflow.com/questions/7482956/java-calendar-getting-time-for-the-timezone) – DavidPostill Aug 11 '14 at 18:08
  • @DavidPostill That question had more to do with printing a correctly formatted date which is a bit different from what I am looking for. – idipous Aug 11 '14 at 21:22

1 Answers1

2

I have read how Date returns the Millis from the Epoch but I would expect that it would return the millis from the Epoch of the date I ask from the Calendar.

Then your expectation is incorrect - or you're not expressing your expectation clearly. There's only one Unix epoch: it's midnight UTC. A Date has no concept of a time zone - it's just the number of milliseconds since the Unix epoch.

It's not clear what your DateUtils class is, but anything which claims to truncate a Date to a day without specifying a time zone is somewhat dubious.

I would strongly advise you to use Joda Time or the Java 8 java.time classes - they're much simpler to work with than java.util.*. If you must use java.util.Date and java.util.Calendar, you'll need to work out which time zone you're interested, and specify that appropriately - using Calendar, not Date - when performing operations such as "truncate to day".

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you for your input. However I need to understand what is wrong with the code I have used since this kind of Date/Calendar usage is repeated in many places in an application I have inherited and if this part is wrong then others will be also. – idipous Aug 11 '14 at 21:16
  • @idipous: well you haven't shown us half the code (e.g. DateUtils.truncate) so we can't help you correct that. I suspect you'll need to go through all date handling code *very* carefully... ideally replacing it with Joda or java.time as you go. – Jon Skeet Aug 11 '14 at 21:18
  • @idipous: Okay. Well you'd need to write an overload taking a time zone, and set the time zone on the calendar. Otherwise it will use the system default time zone. – Jon Skeet Aug 11 '14 at 21:21
  • so you mean `Calendar gval = Calendar.getInstance();` is to blame here right? I thought that `gval.setTime(date)` would take care of that but then again date is just millis sine the epoch in UTC. Then what does it do there? What is its function? – idipous Aug 11 '14 at 21:25
  • @idipous: I don't have time to answer now. But just remember that a Date is an instant in time, whereas a day depends on a time zone. – Jon Skeet Aug 11 '14 at 21:26
  • Thank you. Using the truncate with the Calendar parameter instead of the date did the trick. Now I got the answer to my last question as well. – idipous Aug 11 '14 at 21:55