Calendar.getInstance(TimeZone.getTimeZone("UTC")) is not returning UTC time

I am really confused with the result I am getting with Calendar.getInstance(TimeZone.getTimeZone("UTC")) method call, it's returning IST time.

Here is the code I used

Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());

and the response I got is:

Sat Jan 25 15:44:18 IST 2014

So I tried changing the default TimeZone to UTC and then I checked, then it is working fine

Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());


TimeZone tz  = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Calendar cal_Three = Calendar.getInstance();
System.out.println(cal_Three.getTime());
TimeZone.setDefault(tz);

Result:

Sat Jan 25 16:09:11 IST 2014
Sat Jan 25 10:39:11 UTC 2014

Am I missing something here?

207683 次浏览

System.out.println(cal_Two.getTime())调用从 getTime()返回一个 Date。正是 Date被转换为 println的字符串,在您的情况下,这种转换将使用默认的 IST时区。

您需要显式地使用 DateFormat.setTimeZone()在所需的时区内打印 Date

编辑: 由@Laurynas 提供,想想这个:

TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("EE MMM dd HH:mm:ss zzz yyyy", Locale.US);
simpleDateFormat.setTimeZone(timeZone);


System.out.println("Time zone: " + timeZone.getID());
System.out.println("default time zone: " + TimeZone.getDefault().getID());
System.out.println();


System.out.println("UTC:     " + simpleDateFormat.format(calendar.getTime()));
System.out.println("Default: " + calendar.getTime());

尝试使用 GMT而不是 UTC。它们指的是同一个时区,但是名称 GMT更常见,可能有效。

java.util.Date与时区无关。当您在 Calendar实例的时区设置为 UTC的情况下输出 cal_Two时,cal_Two.getTime()将返回一个没有时区的 Date实例(并且总是在默认时区中)

Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());
System.out.println(cal_Two.getTimeZone());

产出:

 Sat Jan 25 16:40:28 IST 2014
sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

来自 TimeZone.setDefault()的 javadoc

设置由 getDefault 方法返回的 TimeZone 为 null 时,将默认值重置为 VM 时的初始值 第一次开始。

Hence, moving your setDefault() before cal_Two is instantiated you would get the correct result.

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());


Calendar cal_Three = Calendar.getInstance();
System.out.println(cal_Three.getTime());

产出:

Sat Jan 25 11:15:29 UTC 2014
Sat Jan 25 11:15:29 UTC 2014
Calendar currentTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
currentTime.set(Calendar.ZONE_OFFSET, TimeZone.getTimeZone("UTC").getRawOffset());
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, currentTime.get(Calendar.HOUR_OF_DAY));
calendar.getTimeInMillis()

对我很有效

    Following code is the simple example to change the timezone
public static void main(String[] args) {
//get time zone
TimeZone timeZone1 = TimeZone.getTimeZone("Asia/Colombo");
Calendar calendar = new GregorianCalendar();
//setting required timeZone
calendar.setTimeZone(timeZone1);
System.out.println("Time :" + calendar.get(Calendar.HOUR_OF_DAY)+":"+calendar.get(Calendar.MINUTE)+":"+calendar.get(Calendar.SECOND));


}

如果您希望看到时区列表,这里是以下代码

public static void main(String[] args) {


String[] ids = TimeZone.getAvailableIDs();
for (String id : ids) {
System.out.println(displayTimeZone(TimeZone.getTimeZone(id)));
}


System.out.println("\nTotal TimeZone ID " + ids.length);


}


private static String displayTimeZone(TimeZone tz) {


long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset())
- TimeUnit.HOURS.toMinutes(hours);
// avoid -4:-30 issue
minutes = Math.abs(minutes);


String result = "";
if (hours > 0) {
result = String.format("(GMT+%d:%02d) %s", hours, minutes, tz.getID());
} else {
result = String.format("(GMT%d:%02d) %s", hours, minutes, tz.getID());
}


return result;


}

你肯定错过了一件小事,那就是你没有设置默认值:

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

所以代码应该是这样的:

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Calendar cal_Two = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(cal_Two.getTime());

说明 : 如果您想更改时区,请使用 TimeZone.setDefault()设置默认时区

对我很有效。

进入 Timestamp 类型:

public static Timestamp getCurrentTimestamp() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
final Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
Timestamp ts = new Timestamp(date.getTime());
return ts;
}

Get in String type:

    public static String getCurrentTimestamp() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
final Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
Timestamp ts = new Timestamp(date.getTime());
return ts.toString();
}