Java 特定时区中日历中的日期getTime()

Java 特定时区中日历中的日期getTime(),java,date,datetime,Java,Date,Datetime,我有以下代码: Date now = CalendarUtils.getCalendar(getDefaultTimeZone()) .getTime(); CalendarUtils类具有以下方法 public static Calendar getCalendar(final TimeZone tz) { return getCalendar(CalendarUtils.getDate(), tz); } public static Calenda

我有以下代码:

Date now = CalendarUtils.getCalendar(getDefaultTimeZone())
                .getTime();
CalendarUtils类具有以下方法

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());
}
其中getDefaultTimeZone()返回特定时区中的时区对象。比如说欧洲/马德里

但是,我的应用程序运行在罗马的服务器上

问题是上面的代码用于获取马德里的当地时间。因此,8月8日上午12:30在罗马,马德里仍然是8月7日晚上11:30

 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();

    }
当我使用

Date startOfDay = DateUtils.truncate(now, Calendar.DATE);
我希望8月7日00:00:00,而不是8月8日00:00:00

我已经读过Date是如何从历法中返回毫秒的,但我希望它会从我从历法中要求的日期的历法中返回毫秒

当我在罗马时间8月8日上午12:30使用下面的查询时,利用这两个日期(现在和startOfDay),我得到的结果是8月8日,而不是7日(马德里当地时间)

当我说返回我向
日历要求的日期的毫位数时,我的意思是,如果日历提供了8月7日晚上11:30(因为我提供了一个时区),那么我预计从历元到8月7日11:30的毫位数会根据该时区进行调整。这是一个错误的期望吗

我已经读过Date是如何从历法中返回毫秒的,但我希望它会从我从历法中要求的日期的历法中返回毫秒

那么你的期望是不正确的——或者你没有清楚地表达你的期望。只有一个Unix时代:UTC午夜。
Date
没有时区的概念-它只是Unix时代以来的毫秒数

不清楚您的
DateUtils
类是什么,但是任何声称将
Date
截断为一天而不指定时区的东西都有点可疑


我强烈建议您使用或Java 8
Java.time
类-它们比
Java.util.*
简单得多。如果必须使用
java.util.Date
java.util.Calendar
,则在执行诸如“截短到天”之类的操作时,需要确定您感兴趣的时区,并适当地指定该时区-使用
Calendar
,而不是
Date
.

可能重复@DavidPostill该问题与打印格式正确的日期有关,该日期与我要查找的日期稍有不同。感谢您的输入。但是,我需要了解我使用的代码有什么问题,因为在我继承的应用程序中,这种日期/日历用法在许多地方重复出现,如果这部分错误,那么其他部分也会错误。@idipous:您还没有向我们展示一半的代码(例如DateUtils.truncate),因此我们无法帮助您更正。我想你需要仔细检查所有的日期处理代码。。。理想情况下,用Joda或java.time代替它。@idipous:好的。你需要写一个带时区的重载,并在日历上设置时区。否则它将使用系统默认时区在这里是罪魁祸首,对吗?我原以为
gval.setTime(date)
会解决这个问题,但在UTC中,日期只是纪元的毫秒正弦。那它在那里做什么呢?它的作用是什么?@idipous:我现在没时间回答。但请记住,日期是时间上的一个瞬间,而一天取决于时区。
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();
}