我需要将2014年4月9日格林尼治标准时间20:36:13转换为法国时区。
我遇到了这个函数,但无法将其适应我的代码。
long ts = System.currentTimeMillis();
Date localTime = new Date(ts);
String format = "dd MMMM yyyy HH:mm";
SimpleDateFormat sdf = new SimpleDateFormat(format);
// Convert Local Time to UTC (Works Fine)
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Date gmtTime = new Date(sdf.format(localTime));
System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:"
+ gmtTime.toString() + "," + gmtTime.getTime());
// **** YOUR CODE **** END ****
// Convert UTC to Local Time
Date fromGmt = new Date(gmtTime.getTime() + TimeZone.getDefault().getOffset(localTime.getTime()));
System.out.println("UTC time:" + gmtTime.toString() + "," + gmtTime.getTime() + " --> Local:"
+ fromGmt.toString() + "-" + fromGmt.getTime());
有什么想法吗。
Meno Hochschild的回答是正确的。
Joda时间
使用Joda Time 2.3库可以使这项工作更加容易。
String input = "9 Apr 2014 20:36:13 GMT";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "d MMM yyyy HH:mm:ss z" ).withLocale( Locale.ENGLISH );
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTime = formatter.withZone( timeZoneParis ).parseDateTime( input );
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
String output = formatter.withZone( timeZoneParis ).print( dateTime );
转储到控制台…
System.out.println( "input: " + input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "output: " + output );
运行时…
input: 9 Apr 2014 20:36:13 GMT
dateTime: 2014-04-09T22:36:13.000+02:00
dateTimeUtc: 2014-04-09T20:36:13.000Z
output: 9 Apr 2014 22:36:13 CEST
重写任务是将一个时间戳string转换为另一个字符串更改时区。您的代码尝试转换与任务不一致的Date
对象。
Date
-对象没有内部时区,根据规范只引用UTC时区。这一基本事实不受其使用默认时区的toString()
-方法奇怪且极其令人困惑的输出的影响。因此,尝试将一个Date
-对象转换为另一个时区是无稽之谈(它现在和现在都在UTC时区,通过其方法getTime()
可以观察到该状态,该方法在UTC时区中产生自1970-01-01T00:00:000000以来经过的毫秒数)。
关于您的输入"2014年4月9日20:36:13 GMT",您需要:
// Use d, not dd for one or two day digits, use s for second, use z for timezone abbreviations
String format = "d MMM yyyy HH:mm:ss z";
// specify the locale and timezone for input, "Apr" sounds like English
SimpleDateFormat formatGMT = new SimpleDateFormat(format, Locale.ENGLISH);
formatGMT.setTimeZone(TimeZone.getTimeZone("GMT"));
// specify the locale and timezone for output, use a valid timezone identifier (IANA)
SimpleDateFormat formatFrance = new SimpleDateFormat(format, Locale.ENGLISH);
formatFrance.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
String input = "9 Apr 2014 20:36:13 GMT";
Date d = formatGMT.parse(input);
String output = formatFrance.format(d);
// the offset in April (summer time) is TWO hours, not one
System.out.println(output); // 9 Apr 2014 22:36:13 CEST
如果你真的想做日期运算,比如夏天减去一小时,冬天加一小时,你需要:
boolean summerTime = TimeZone.getTimeZone("Europe/Paris").inDaylightTime(d);
if (summerTime) {
d = new Date(d.getTime() - 3600 * 1000L);
} else {
d = new Date(d.getTime() + 3600 * 1000L);
}
String output = formatFrance.format(d);
In winter you get: 9 Mar 2014 22:36:13 CET (input was in March)
In summer you get: 9 Apr 2014 21:36:13 CEST
试试这个。。告诉我它对你有用吗。
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd MMM yyyy HH:mm");
java.util.TimeZone timeZonecurr = java.util.TimeZone.getTimeZone("Etc/GMT");
java.util.TimeZone timeZoneto = java.util.TimeZone.getTimeZone("Etc/GMT+2");
sdf.setTimeZone(timeZonecurr);
java.util.Calendar calendar = new java.util.GregorianCalendar(timeZonecurr);
System.out.println("Current Time in Etc/GMT = " + sdf.format(calendar.getTime()));
calendar.setTimeZone(timeZoneto);
sdf.setTimeZone(timeZoneto);
System.out.println("Current Time in Etc/GMT+2 = " + sdf.format(calendar.getTime()));
Date
没有附加时区。它只是一个时间点。只有在Date
和String
之间转换时,时区才会起作用,反之亦然。
这意味着,当您读取日期时,您只需使用绑定到GMT的格式(将其从String
转换为Date
),然后当您将其转换回String
时,您将使用另一种绑定到法国的格式。