2014-01-14 76 views
1

我有一个时间戳,我试图把它放到一个Date对象中,但是当我使用Calendar时,我遇到了一个奇怪的问题。我似乎能不能创建一个Date对象我想要的值:如何使用TimeZone设置日历?

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 

这就是我要寻找的结果,但我担心,如果我上运行机器不在同一时区运行,我不会得到一致的行为。

回答

1

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

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

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

,当没有找到所请求的时区没有警告产生的不幸来获得。

2

这就是我要寻找的结果,但我担心,如果我未在相同的时区

运行的机器上运行它的问题。内部表示应该没问题,但它会在当地时区打印:表示与实际内容不同。

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

+0

都能跟得上。 SimpleDateFormat(“EEE MMM dd HH:mm:ss zzz yyyy”)会产生相同的结果。 – xirt

+0

您是否设置了SimpleDateFormat的TimeZone?它使用JVM TimeZOne! – venergiac

0

如果你能做到废除java.util.Date,您可以使用joda时间API方便地设置这些值作为期望:

为您查询,您可以设置已创建的日历实例作为构造函数参数DateTime

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

输出:

2014-01-14T04:00:00.064-05:00 
0

Calendar.getTime()返回java.util.Date对象。对象不知道任何关于时区的信息。 Calendar.getTime()返回的Date对象不知道它来自哪个时区的Calendar设置。

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

如果要在特定时区打印Date,请使用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())); 
0

的Java日期对象表示1970年1月1毫秒的秒数,00:00:00 GMT由于这样的事实,其他方法已被弃用。直接“查看”Date对象的两种方法是“getTime()”和“toString()”(使用“dow mon dd hh:mm:ss zzz yyyy”)。因此,您正在将GMT值格式化为当地时区。

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

0

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

避免java.util.Date &。Calendar类。

切勿对时区使用三字母代码。它们既不标准也不唯一。请使用proper time zone names。在这种情况下,请使用“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(); 

转储到控制台...

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

当运行...

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