我将给出时区的输入日期时间和输入日期时间的时区,我们希望相关的日期时间在预期的时区。
这是我的方法。 convertToTimezone(“03/08/2010 20:19:00 PM”,“Asia / Shanghai”,“US / Central”); 以上时间是亚洲/上海的时间。我们想知道美国/中部的相应时间。
它工作正常,但我与实际时间相差1小时。 我能知道我哪里出错吗?
这是代码。
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateUtil
{
private static String format_date="MM/dd/yyyy HH:mm:ss a";
public static void main(String a[])
{
try
{
String sourceTimezone="Asia/Shanghai";
String destTimezone="US/Central";
String outputExpectedTimezone=convertToTimezone("03/08/2010 20:19:00 PM",sourceTimezone,destTimezone);
System.out.println("outputExpectedTimezone :"+outputExpectedTimezone);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public static String convertToTimezone(String inputDate,String inputDateTimezone,String destinationDateTimezone)throws Exception
{
String outputDate=null;
SimpleDateFormat format = new SimpleDateFormat(format_date);
format.setTimeZone(TimeZone.getTimeZone(inputDateTimezone));
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(inputDateTimezone));
calendar.setTime(format.parse(inputDate));
calendar.add(Calendar.MILLISECOND,-(calendar.getTimeZone().getRawOffset()));
calendar.add(Calendar.MILLISECOND, - calendar.getTimeZone().getDSTSavings());
calendar.add(Calendar.MILLISECOND, TimeZone.getTimeZone(destinationDateTimezone).getRawOffset());
outputDate=format.format(calendar.getTime());
return outputDate;
}
}
答案 0 :(得分:2)
您不应该在日历中添加任何内容 - 这代表特定的即时时间。实际上,您根本不需要日历。
相反,有两种不同的格式,每个时区一个:
public static String convertToTimezone(String inputDate,
String inputDateTimezone,
String destinationDateTimezone)
throws Exception
{
SimpleDateFormat parser = new SimpleDateFormat(format_date);
parser.setTimeZone(TimeZone.getTimeZone(inputDateTimezone));
Date date = parser.parse(inputDate);
SimpleDateFormat formatter = new SimpleDateFormat(format_date);
formatter.setTimeZone(TimeZone.getTimeZone(outputDateTimezone));
return formatter.format(date);
}
另外,我彻底建议使用Joda Time而不是内置的日期/时间API。
答案 1 :(得分:0)
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
另外,下面引用的是来自 home page of Joda-Time 的通知:
<块引用>请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。
使用 java.time
(现代日期时间 API)的解决方案:
LocalDateTime
ZonedDateTime
ZonedDateTime#withZoneSameInstant
将此 ZonedDateTime
转换为目标 ZonedDateTime
ZonedDateTime
。演示:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(convertToTimezone("03/08/2010 20:19:00 PM", "Asia/Shanghai", "US/Central"));
System.out.println(convertToTimezone("03/08/2010 20:19:00 PM", "Asia/Shanghai", "America/Mexico_City"));
}
static String convertToTimezone(String inputDate, String inputDateTimezone, String destinationDateTimezone) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(inputDate, dtf);
ZonedDateTime zdtInput = ldt.atZone(ZoneId.of(inputDateTimezone));
ZonedDateTime zdtDestination = zdtInput.withZoneSameInstant(ZoneId.of(destinationDateTimezone));
return zdtDestination.format(dtf);
}
}
输出:
03/08/2010 06:19:00 AM
03/08/2010 06:19:00 AM
注意:避免使用已弃用的 ID US/Central
。使用标准 ID America/Mexico_City
其中 Mexico City is the largest city in this timezone。
从 Trail: Date Time 了解有关现代 Date-Time API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。