首页 > 解决方案 > 本地到 GMT,反之亦然 - 日期和时间转换不起作用

问题描述

我试图将输入日期时间转换为 GMT+0 ,然后将其转换回本地时间。虽然本地到 GMT+0 转换有效,但后来的转换-gmt 到本地失败!

Calendar cal=Calendar.getInstance();
cal.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(cal.getTime()));
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(cal.getTime()));

//now i want to get my local time from this converted gmt+0 standard time
String standdardTimeStr=sdf.format(cal.getTime());
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date=sdf2.parse(standdardTimeStr);
Calendar cal2= Calendar.getInstance();
cal2.setTime(date);
System.out.println("standard input time:"+ sdf2.format(cal2.getTime()));
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka

System.out.println("gmt+6 convertedtime:"+ sdf2.format(cal2.getTime()));

这是我的输出:

my inputTime:2020-07-13T15:02:16.849
gmt+0 converted time:2020-07-13T09:02:16.849
standard input time:2020-07-13T09:02:16.849 //taking upper line as input-gmt+0
gmt+6 convertedtime:2020-07-13T09:02:16.849 //this date was supposed to be same as the first date

请指出我在编码或概念上做错了什么?

标签: javadatetime

解决方案


我不知道你为什么要使用一个Calendar对象。JavadocCalendar.getInstance()说:

返回的 Calendar 基于默认时区的当前时间

这意味着调用cal.setTime(new Date());是完全多余的。

但是,更糟糕的是,以下三个都是一样的:

// The very long way
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
Date date = cal.getTime();

// The long way
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();

// The simple way
Date date = new Date();

对象始终以DateUTC (GMT+0) 存储日期/时间。解析字符串和格式化字符串时应用时区。

解析未指定时区偏移量的字符串将在 的时区中解析,SimpleDateFormat除非另有指定,否则该时区是默认时区(也称为“本地”时区),并将解析值转换为 UTC存储在Date对象中。

将值格式化Date为字符串将始终使用SimpleDateFormat.


清理问题中的代码以不使用Calendar,因为这只会混淆问题,并对其进行评论以显示正在发生的事情,将回答您的“指出我在编码或概念上做错了什么”的问题:

Date now = new Date();

// Format the date in the local time zone
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(now));

// Format the date in GMT time zone
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(now));

// Format the date in GMT time zone (again), since the time     ** ERROR MIGHT **
// zone of the formatter is still set to GMT                    **   BE HERE   **
String standdardTimeStr = sdf.format(now);

// Parse the GMT date string as-if it is in local time zone   ** OR MAYBE HERE **
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date = sdf2.parse(standdardTimeStr); // Date value here is wrong

// Format the bad date value back to string in the same time
// zone, which means you get GMT time back, even though that
// is not the value of the `date` variable
System.out.println("standard input time:"+ sdf2.format(date));

// Do it again, same result, because the time zone is changed    ** ERROR HERE **
// on the wrong formatter object
sdf.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka
System.out.println("gmt+6 convertedtime:"+ sdf2.format(date));

推荐阅读