java.util.Calendar和时区存在问题

java.util.Calendar和时区存在问题,java,calendar,timezone,Java,Calendar,Timezone,我有以下方法将自定义DMY(日期、月份、年份)对象转换为日期 public static Date serverCreateDateFromDMY(DMY pDMY, TimeZone pTimeZone) { Calendar vCalendar = Calendar.getInstance(pTimeZone); vCalendar.set(Calendar.YEAR, pDMY.getYear()); // Below lin

我有以下方法将自定义DMY(日期、月份、年份)对象转换为日期

public static Date serverCreateDateFromDMY(DMY pDMY, TimeZone pTimeZone)
    {
        Calendar vCalendar = Calendar.getInstance(pTimeZone);
        vCalendar.set(Calendar.YEAR, pDMY.getYear());
            // Below line is because DMY month counts are 1-indexed
            // and Date month counts are 0-indexed
        vCalendar.set(Calendar.MONTH, pDMY.getMonthOfYear() - 1);
        vCalendar.set(Calendar.DAY_OF_MONTH, pDMY.getDayOfMonth());
        System.out.println(vCalendar.getTime());
        TimeUtilsServer.zeroCalendarHoursAndBelow(vCalendar);
        System.out.println(vCalendar.getTime());
        return vCalendar.getTime();
    }


public static void zeroCalendarHoursAndBelow(Calendar pToZero)
    {
        pToZero.set(Calendar.HOUR_OF_DAY, 0);
        pToZero.set(Calendar.MINUTE, 0);
        pToZero.set(Calendar.SECOND, 0);
        pToZero.set(Calendar.MILLISECOND, 0);
    }
我将这些参数传递给serverCreateDateFromDMY()方法:DMY=20120424,时区为:America/NewYork。应用程序正在我的时区(IST)本地运行

根据上述输入,打印以下输出

Tue Apr 24 14:43:07 IST 2012

Tue Apr 24 09:30:00 IST 2012
正如你们所看到的,在最后一次输出中,时间并没有归零。有什么建议吗

@Marko,是的,我了解了DateFormat,并尝试了以下示例。但是,日期仍然是随时间打印的,而不是归零

TimeZone tz = TimeZone.getTimeZone("America/New_York");
        Calendar vCalendar = Calendar.getInstance(tz);
        vCalendar.set(Calendar.YEAR, 2012);

        vCalendar.set(Calendar.MONTH, 4 - 1);
        vCalendar.set(Calendar.DAY_OF_MONTH, 24);
        DateFormat df = DateFormat.getDateTimeInstance();
        df.setTimeZone(tz); 
        System.out.println(df.format(vCalendar.getTime()));

         vCalendar.set(Calendar.HOUR_OF_DAY,     vCalendar.getActualMinimum(Calendar.HOUR_OF_DAY));
        vCalendar.set(Calendar.MINUTE, vCalendar.getActualMinimum(Calendar.MINUTE));
        vCalendar.set(Calendar.SECOND, vCalendar.getActualMinimum(Calendar.SECOND));
        vCalendar.set(Calendar.MILLISECOND,   vCalendar.getActualMinimum(Calendar.MILLISECOND));
        System.out.println(df.format(vCalendar.getTime()));

java日期/时间API从创建时起就有一个糟糕的设计。也许您应该看看一些库——例如,它隐藏了JDK API的缺陷——

。。。你比纽约时间早9:30。您将时间设置为纽约时间午夜,并将其作为您所在区域的时间读出。请注意,
getTime
返回一个不可配置时区的
Date
。如果要指定打印结果的时区,则需要
DateFormat

在内部,日期和日历对象存储在UTC中。将字段设置为0时,日历将以UTC更新


当您向日历询问时间时,它会将日期转换为您所需的时区,从而产生差异。

TimeUtilsServer是如何实现的?日期始终以UTC为单位,从不以系统时区为单位。日期实际上是时间上的一个绝对时刻,其他类的任务是以他们认为合适的方式表示该时刻。日历以UTC更新也是不正确的——它是相对于您构建它的时区的。如果您没有使用任何时区,那么它是系统默认时区。不管怎么说,这很复杂。谢谢Marko。是的,我知道了。然后我用DateFormat做了一个简单的例子,但它仍然不能用零时间打印日期。我在评论中有字符限制,所以我不能在这里发布整个示例。最好的方法是更新您的问题以反映您的新工作,包括代码和新的错误行为。对于上下文,您可以将其添加到底部,并用UPDATE命名。是的,我已经更新了我的问题,并添加了我所做的小示例。它在2012年4月24日6:13:13 AM 2012年4月24日12:00:00 AM之后打印这实际上是正确的输出。让你困惑的可能只是默认的日期格式,它使用美国的AM/PM系统。该输出以24小时格式表示00:00。请参阅
SimpleDateFormat
中关于指定日期格式的Javadoc。是的,Marko,使用SimpleDateFormat最终为我提供了正确的显示。谢谢你的反馈。这是我使用的格式<代码>SimpleDataFormat sdf=新SimpleDataFormat(“yyyy-MM-dd HH:MM:ss,zzzz”);设置时区(tz)你好,巴克斯。我同意你的看法。事实上,我们正在重新设计我们的产品,我们正在用joda Time替换这个笨拙的java日期/时间API。