格式化Calendar对象而不是Date对象?

时间:2012-10-18 22:18:32

标签: java calendar formatting simpledateformat

我正在尝试格式化日历字符串以指示除本地字符串以外的时区偏移量。我知道我可以创建一个简单的格式化字符串并使用Calendar.get(int)方法填充所有值,但这不是正确的方法。

Java有一个DateFormat,具体来说我正在尝试使用SimpleDateFormat。问题是这些类的format()方法需要一个Date对象。

我主要使用Calendar个对象,因为我认为这些是Java推荐的结构。因此,当我去格式化结果时间时,我调用Calendar.getTime(),它返回一个Date对象,该对象可以传递给SimpleDateFormat对象。

到目前为止,我认为这非常简单,但问题就在这里。

每当调用Calendar.getTime()方法时,无论Date的时区如何,返回的Calendar始终位于本地时区。

所以,当我把它传递给我的SimpleDateFormat时,我总是把时间打印在当地时区,这不是我想要的。到目前为止我所做的所有研究都表示无法完成,我所看到的所有示例都只是使用Calendar.get(int)方法来填补一些空白。这看起来很可怕,为什么有一个DateFormat类,如果它会变得如此无用?

以下是一些示例代码,您可以看到我的意思,将其粘贴到您最喜欢的测试类中:

private static final SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

public static void main(String[] args)
{
    try
    {
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
        cal.setTimeInMillis(parser.parse("2012-10-09T22:01:49.108-0700").getTime());
        System.out.println(formatter.format(cal.getTime()));
    }
    catch(ParseException e)
    {
        e.printStackTrace();
    }
}

产生的输出(因为我在中央时区运行):2012-10-10T00:01:49-0500
预期产出(无论从哪个时区运行):2012-10-10T01:01:49-0400

总结一下问题:有没有办法让java中的DateFormat接受一个Calendar,或者一种方法来获取一个不在本地时区的Date,或者是否有另一个类我应该一起使用这个格式?

3 个答案:

答案 0 :(得分:2)

  

每当调用Calendar.getTime()方法时,无论日历的时区如何,返回的日期始终位于本地时区。

不,不是。 Date 没有时区。它只是自Unix时代以来的毫秒数。其toString()方法转换为本地时区,但这不是Date对象中信息的一部分。

您需要做的就是将格式化程序的时区设置为与日历的时区相同。

formatter.setTimeZone(calendar.getTimeZone());

...或者只是将日历设置为完全使用:

formatter.setCalendar(calendar);

(我不能立即明白后一种方法是否意味着日历会失去其价值......基本上Java类将“日历系统”,“时区”和“日历中的价值”混合在一起类型,这是非常不幸的。)

我同意Ian的观点,就Joda Time而言,它是一个更令人愉快的API。

答案 1 :(得分:0)

我会放弃内置的java日期和时间类,而是使用joda time。它被设计为正确处理ISO8601格式字符串并使用时区做正确的事情。

答案 2 :(得分:0)

日期没有任何TimeZone,它只是Epoch时间以来的毫秒数,以人类可读的格式表示。我们可以使用“DateFormat”类。

 TimeZone tz = TimeZone.getTimeZone("America/Buenos_Aires");
 Calendar cal = Calendar.getInstance(tz);
 Date d = cal.getTime();
 DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm aaa");
 df.setTimeZone(tz);
 String s = df.format(cal.getTime());
 System.out.println(s);