1

我有一个试图放入Date对象的时间戳,但是当我使用日历时,我遇到了一个奇怪的问题。我似乎无法使用我想要的值创建 Date 对象:

public static void main(String args[]){
    Date today = new Date();
    int hour = 4, min=0, sec=0, ms=64;

    Calendar cal = GregorianCalendar.getInstance();

    cal.clear();
    cal.setTimeZone(TimeZone.getTimeZone("EDT"));
    cal.setTime(today);
    cal.set(Calendar.HOUR_OF_DAY,hour);
    cal.set(Calendar.MINUTE,min);
    cal.set(Calendar.SECOND,sec);
    cal.set(Calendar.MILLISECOND,ms);

    System.out.println("Time is: "+cal.getTime());
}

这会产生:

Time is: Mon Jan 13 23:00:00 EST 2014

不是我要找的结果。

但是,如果我注释掉“setTimeZone”方法调用,我会得到以下结果:

Time is: Tue Jan 14 04:00:00 EST 2014

这是我正在寻找的结果,但我担心如果我在不在同一时区运行的机器上运行,我将无法获得一致的行为。

4

6 回答 6

2

这是我正在寻找的结果,但我担心如果我在不在同一时区运行的机器上运行

这是问题所在。内部表示应该没问题,但它打印在本地时区:表示不同于真实内容

使用SimpleDateFormat http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html并设置 TimeZone 以查看所需区域的日期。

于 2014-01-14T20:31:08.460 回答
1

这里的问题是 Java 不知道时区“EDT”(东部夏令时间)。因此,日历似乎将时区设置为 GMT。

这里需要的时区是“America/New_York”或“EST5EDT”。当使用这些值中的任何一个时,都会产生正确的结果。

可以通过调用获取有效时区列表TimeZone.getAvailableIDs()

遗憾的是,在未找到请求的时区时不会产生任何警告。

于 2014-01-14T21:47:31.567 回答
0

如果您可以取消java.util.Date,您可以使用joda time API 根据需要方便地设置这些值:

对于您的查询,您可以将已创建的 Calendar 实例作为构造函数参数设置为DateTime.

DateTime dt = new DateTime(cal);
System.out.println(dt.toDateTimeISO());

输出:

2014-01-14T04:00:00.064-05:00
于 2014-01-14T21:21:03.537 回答
0

Calendar.getTime()返回一个java.util.Date对象。Date对象对时区一无所知。返回的Date对象Calendar.getTime()不知道Calendar它来自哪个时区。

当您打印一个Date对象时(例如,通过隐式调用toString()对象,就像您正在做的那样)它会在您运行它的机器的默认时区中格式化。

如果要Date在特定时区打印 a ,请使用 a ,并在对象SimpleDateFormat上设置所需的时区。SimpleDateFormat例如:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("EDT"));

// Will display the date that the calendar is set to in the EDT timezone
System.out.println(df.format(cal.getTime()));
于 2014-01-14T21:25:26.463 回答
0

Java Date 对象表示自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数,因为不推荐使用其他方法。直接“查看”日期对象的两种方法是“getTime()”和“toString()”(使用“dow mon dd hh:mm:ss zzz yyyy”)。因此,您将 GMT 值格式化为您当地的时区。

处理日期时,最好将它们视为 GMT 值,然后在查看日期时将其视为“格式化”练习。

于 2014-01-14T21:32:19.660 回答
0

为了比较,这里是相同类型的代码,但使用的是Joda-Time 2.3。

避免使用 java.util.Date 和 .Calendar 类。

切勿对时区使用三字母代码。它们既不是标准化的,也不是唯一的。而是使用正确的时区名称。在这种情况下,请使用“America/New_York”或“America/Montreal”。

// Use time zone names, such as from this slightly outdated list: http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );

// Input.
int hour = 4, min = 0, sec = 0, ms = 64;

// Start with now, then adjust the time of day.
DateTime now = new DateTime( timeZone );
DateTime dateTime = now.withHourOfDay( hour ).withMinuteOfHour( min ).withSecondOfMinute( sec ).withMillisOfSecond( ms );

// If needed, translate to a java.util.Date for use with other classes.
java.util.Date date = dateTime.toDate();

转储到控制台...</p>

System.out.println( "now: " + now );
System.out.println( "dateTime: " + dateTime );
System.out.println( "date: " + date );

运行时……</p>

now: 2014-01-20T21:04:51.237-05:00
dateTime: 2014-01-20T04:00:00.064-05:00
date: Mon Jan 20 01:00:00 PST 2014
于 2014-01-21T02:06:44.793 回答