Java 全名时区的时间不正确

Java 全名时区的时间不正确,java,datetime,timezone,Java,Datetime,Timezone,我正在尝试使用全名时区将时间从时区转换为另一个时区。下面是我使用的JavaAPI TimeZone.setDefault(TimeZone.getTimeZone("Africa/Algiers")); SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); String dateInString = "09:44:00"; TimeZone tzGMT01 = TimeZone.getTime

我正在尝试使用全名时区将时间从时区转换为另一个时区。下面是我使用的JavaAPI

    TimeZone.setDefault(TimeZone.getTimeZone("Africa/Algiers"));
    SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    String dateInString = "09:44:00";
    TimeZone tzGMT01 = TimeZone.getTimeZone("Africa/Algiers");
    formatter.setTimeZone(tzGMT01);

    Date dateInAmerica = formatter.parse(dateInString);
    String fromInput = formatter.format(dateInAmerica);
    TimeZone tzGMT03 = TimeZone.getTimeZone("Asia/Bahrain");
    formatter.setTimeZone(tzGMT03); 

    String toInput = formatter.format(dateInAmerica);
    Time ts = java.sql.Time.valueOf(toInput);
转换为“亚洲/巴林”时间的时间值
09:44:00
的预期输出为
11:44:00
。但是,输出是
13:44:00

有人能告诉我上面的陈述有什么错吗

它应该可以正常工作,使用您为亚洲/巴林提供的时区:

SimpleDateFormat f = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

Date currentTime = new Date();
System.out.println(f.format(currentTime.getTime()));

f.setTimeZone(TimeZone.getTimeZone("Asia/Bahrain"));
System.out.println(f.format(currentTime.getTime()));
SimpleDataForma将正确地完成这个任务

以下是我的输出:

> 06/18/2016 23:55:13 
> 06/19/2016 05:55:13

您的问题是Java
Date
是完整的日期值,而不仅仅是时间值。如果不提供年/月/日值,则默认值为1970/01/01

1970年的世界已经不同了。当时使用UTC+0时区,当时使用UTC+4,这与今天不同,今天阿尔及尔使用UTC+1时区,巴林使用UTC+3时区

忽略日期也会导致具有夏令时的时区出现问题

如您所见,日期很重要

下面是显示它的代码:

TimeZone tzAlgiers = TimeZone.getTimeZone("Africa/Algiers");
TimeZone tzBahrain = TimeZone.getTimeZone("Asia/Bahrain");

SimpleDateFormat fmtTimeAlgiers = new SimpleDateFormat("HH:mm:ss");
fmtTimeAlgiers.setTimeZone(tzAlgiers);

SimpleDateFormat fmtDatetimeAlgiers = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
fmtDatetimeAlgiers.setTimeZone(tzAlgiers);

SimpleDateFormat fmtFullAlgiers = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z (Z)");
fmtFullAlgiers.setTimeZone(tzAlgiers);

SimpleDateFormat fmtFullBahrain = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z (Z)");
fmtFullBahrain.setTimeZone(tzBahrain);

Date date1970 = fmtTimeAlgiers.parse("09:44:00");
System.out.println(fmtTimeAlgiers.format(date1970) + "                          " + tzAlgiers.getID());
System.out.println(fmtFullAlgiers.format(date1970) + "   " + tzAlgiers.getID());
System.out.println(fmtFullBahrain.format(date1970) + "   " + tzBahrain.getID());
System.out.println();

Date date2016 = fmtDatetimeAlgiers.parse("2016-01-01 09:44:00");
System.out.println(fmtDatetimeAlgiers.format(date2016) + "               " + tzAlgiers.getID());
System.out.println(fmtFullAlgiers.format(date2016) + "   " + tzAlgiers.getID());
System.out.println(fmtFullBahrain.format(date2016) + "   " + tzBahrain.getID());
System.out.println();
输出

09:44:00非洲/阿尔及尔
1970-01-01 09:44:00 CET(+0000)非洲/阿尔及尔
1970-01-01 13:44:00东部时间(+0400)亚洲/巴林
2016-01-01 09:44:00非洲/阿尔及尔
2016-01-01 09:44:00 CET(+0100)非洲/阿尔及尔
2016-01-01 11:44:00东部时间(+0300)亚洲/巴林

1970年的时区名称实际上是错误的。阿尔及尔使用的是
GMT
,巴林使用的是
GST
(海湾标准时间)。

如回答末尾所述,诸如
CET
AST
GST
等3-4个字母的缩写是一个问题。它们不是真正的时区,不是标准化的,也不是唯一的(!)。相反,使用a。这是正确的分析。我将输入时间转换为当前日期,并附加了输入时间。此日期时间值返回了正确的转换值。这很有帮助。非常感谢。