Java 中日期和时间转换为其他时区

问题描述 投票:0回答:12

我编写了这段代码来将当前系统日期和时间转换为其他时区。我没有收到任何错误,但没有得到预期的输出。就像我在特定时间执行我的程序一样..我的输出是::

印度的当前时间是 :: Fri Feb 24 16:09:23 IST 2012



::

中部标准时间 中的日期和时间为 :: Sat Feb 25 03:39:23 IST 2012



根据

CST时区的实际时间是::

Friday, 24 February 4:39:16 a.m(GMT - 6:00)

所以存在一些

时间差距。我不知道为什么会发生这种情况。任何帮助将不胜感激..代码是::

package MyPackage; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class Temp2 { public static void main(String[] args) { try { Calendar currentdate = Calendar.getInstance(); String strdate = null; DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); strdate = formatter.format(currentdate.getTime()); TimeZone obj = TimeZone.getTimeZone("CST"); formatter.setTimeZone(obj); //System.out.println(strdate); //System.out.println(formatter.parse(strdate)); Date theResult = formatter.parse(strdate); System.out.println("The current time in India is :: " +currentdate.getTime()); System.out.println("The date and time in :: "+ obj.getDisplayName() + "is ::" + theResult); } catch (ParseException e) { e.printStackTrace(); } } }
    
java date timezone date-conversion
12个回答
22
投票
它是通过网络进行的。本来可以用谷歌搜索的。无论如何,这是一个适合您的版本(从

here无耻地挑选和修改):

Calendar calendar = Calendar.getInstance(); TimeZone fromTimeZone = calendar.getTimeZone(); TimeZone toTimeZone = TimeZone.getTimeZone("CST"); calendar.setTimeZone(fromTimeZone); calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1); if (fromTimeZone.inDaylightTime(calendar.getTime())) { calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1); } calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset()); if (toTimeZone.inDaylightTime(calendar.getTime())) { calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings()); } System.out.println(calendar.getTime());
    

8
投票
您的错误是拨打

parse

 而不是 
format

您调用

parse

 从字符串中解析日期,但在您的情况下,您有一个日期并且需要使用正确的时区对其进行格式化。

将您的代码替换为

Calendar currentdate = Calendar.getInstance(); DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); TimeZone obj = TimeZone.getTimeZone("CST"); formatter.setTimeZone(obj); System.out.println("Local:: " +currentdate.getTime()); System.out.println("CST:: "+ formatter.format(currentdate.getTime()));

我希望您能得到您期望的输出。


6
投票

SimpleDateFormat#setTimezone()

就是答案。一个带有 
ETC
 时区的格式化程序用于解析,另一个带有 
UTC
 用于生成输出字符串:

DateFormat dfNy = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT); dfNy.setTimeZone(TimeZone.getTimeZone("EST")); DateFormat dfUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT); dfUtc.setTimeZone(TimeZone.getTimeZone("UTC")); try { return dfUtc.format(dfNy.parse(input)); } catch (ParseException e) { return null; // invalid input }
    

4
投票
在我的日常工作中,用 Java 处理日期是一项不小的任务。我建议您使用

Joda-Time 来简化我们的编码工作,并且您不必“重新发明轮子”。


3
投票
您可以使用两种 SimpleDateFormat,一种用于解析 EST 时区的日期字符串,一种用于打印 UTC 时区的日期

String format = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat estFormatter = new SimpleDateFormat(format); estFormatter.setTimeZone(TimeZone.getTimeZone("EST")); Date date = estFormatter.parse("2015-11-01 01:00:00"); SimpleDateFormat utcFormatter = new SimpleDateFormat(format); utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); System.out.println(utcFormatter.format(date));
    

2
投票
您可以使用

“CST6CDT” 因为在一些国家/地区,他们在夏季遵循 CDT,在冬季遵循 CST

public static String getDateInCST() { Calendar calendar = Calendar.getInstance(); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); formatter.setTimeZone(TimeZone.getTimeZone( "CST6CDT")); String strdate = formatter.format(calendar.getTime()); TimeZone.getAvailableIDs(); return strdate; }
    

2
投票
问题是当您打印日期对象时,它会调用

toString

 方法,并且它将在您的机器默认时区中打印。试试这个代码,看看有什么不同。

Calendar currentdate = Calendar.getInstance(); String strdate = null; DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ssz"); strdate = formatter.format(currentdate.getTime()); System.out.println("strdate=>" + strdate); TimeZone obj = TimeZone.getTimeZone("CST"); formatter.setTimeZone(obj); strdate = formatter.format(currentdate.getTime()); Date theResult = formatter.parse(strdate); System.out.println("The current time in India is :: " +currentdate.getTime()); System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + theResult); System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + strdate);
    

1
投票
第一条消息,不要在代码中将日期和时间作为字符串处理。就像您不将数字和布尔值作为字符串处理一样(我希望如此)。使用正确的日期时间对象。

java.time

有时我们会获取日期和时间作为字符串输入。例如,它可能来自文本文件、来自用户或来自与另一个系统的数据交换。在这些情况下,首先要解析为正确的日期时间对象。第二条消息,使用 java.time(现代 Java 日期和时间 API)来进行日期和时间工作。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"); String input = "2015-11-01 01:00:00"; ZonedDateTime nyTime = LocalDateTime.parse(input, formatter) .atZone(ZoneId.of("America/New_York")); System.out.println("Time in New York: " + nyTime);

此片段的输出是:

Time in New York: 2015-11-01T01:00-04:00[America/New_York]


转换为 GMT:

OffsetDateTime gmtTime = nyTime.toOffsetDateTime() .withOffsetSameInstant(ZoneOffset.UTC); System.out.println("GMT Time: " + gmtTime);

GMT Time: 2015-11-01T05:00Z


如果需要提供字符串输出,请使用日期时间格式化程序进行格式化。以下是针对美国观众的格式示例:

DateTimeFormatter userFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) .withLocale(Locale.US); String formattedDateTime = gmtTime.format(userFormatter); System.out.println("GMT Time formatted for user: " + formattedDateTime);

GMT Time formatted for user: Nov 1, 2015, 5:00:00 AM


您还问:

在下面的两个结果中,您应该选择哪一个?

我理解您这么问,因为这两个答案都是有效的。 2015 年 11 月 1 日夏令时 (DST) 于凌晨 2 点结束。也就是说,01:59:59 之后第二次来到了 01:00:00。因此,当我们得到

2015-11-01 01:00:00

 作为输入时,它是不明确的。它可能采用东部夏令时间,等于 05:00 GMT,也可能采用东部标准时间,晚一小时,因此等于 06:00 GMT。我无法告诉您哪一个对于您的情况是正确的。您可以使用 
withEarlierOffsetAtOverlap()
withLaterOffsetAtOverlap()
 控制获得的结果。上面我们得到了 DST 解释。因此要获得标准时间解释:

nyTime = nyTime.withLaterOffsetAtOverlap(); System.out.println("Alternate time in New York: " + nyTime);

纽约替代时间:2015-11-01T01:00-05:00[America/New_York]

我们注意到一天中的时间仍然是 01:00,但偏移量现在是

-05:00

 而不是 
-04:00
。这也给了我们不同的 GMT 时间:

GMT Time: 2015-11-01T06:00Z GMT Time formatted for user: Nov 1, 2015, 6:00:00 AM


避免 SimpleDateFormat 和朋友

虽然其他答案通常是正确的,但其中使用的类

DateFormat

SimpleDateFormat
Date
Calendar
 设计不佳且早已过时。前两个特别麻烦。我建议您避免所有这些。坦率地说,我发现现代 API 更好用。

链接

Oracle 教程:日期时间 解释如何使用 java.time。


1
投票

2020年答案在这里

如果您想要新的

java.time.*

 功能但仍想搞乱 
java.util.Date
:

public static Date convertBetweenTwoTimeZone(Date date, String fromTimeZone, String toTimeZone) { ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone); ZoneId toTimeZoneId = ZoneId.of(toTimeZone); ZonedDateTime fromZonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).withZoneSameLocal(fromTimeZoneId); ZonedDateTime toZonedDateTime = fromZonedDateTime .withZoneSameInstant(toTimeZoneId) .withZoneSameLocal(ZoneId.systemDefault()) ; return Date.from(toZonedDateTime.toInstant()); }
对于

java.sql.Timestamp


public static Timestamp convertBetweenTwoTimeZone(Timestamp timestamp, String fromTimeZone, String toTimeZone) { ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone); ZoneId toTimeZoneId = ZoneId.of(toTimeZone); LocalDateTime localDateTimeBeforeDST = timestamp.toLocalDateTime(); ZonedDateTime fromZonedDateTime = ZonedDateTime.of(localDateTimeBeforeDST, fromTimeZoneId); ZonedDateTime toZonedDateTime = fromZonedDateTime.withZoneSameInstant(toTimeZoneId); return Timestamp.valueOf(toZonedDateTime.toLocalDateTime()); }
    

0
投票
请参考下面提到的代码。

DateFormat utcConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); utcConverter.setTimeZone(TimeZone.getTimeZone("GMT")); String sampleDateTime = "2015-11-01 01:00:00"; DateFormat nyConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); nyConverter.setTimeZone(TimeZone.getTimeZone("EST")); Calendar nyCal = Calendar.getInstance(); nyCal.setTime(nyConverter.parse(sampleDateTime)); System.out.println("NY TIME :" +nyConverter.format(nyCal.getTime())); System.out.println("GMT TIME :" +utcConverter.format(nyCal.getTime()));
    

0
投票

对于谷歌日历API

private String getFormatedDate(Date date) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+05:30"); df.setTimeZone(TimeZone.getTimeZone("GMT+05:30")); return df.format(date); }
    

0
投票

使用新的 Java 8 java.time API

import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; public class Java8TimeZoneConversion { public static void main(String[] args) { // Current date and time using now() ZonedDateTime currentDateTime = ZonedDateTime.now(); // Creating two timezone zoneid objects using ZoneId.of() method. ZoneId losAngelesTimeZone = ZoneId.of("America/Los_Angeles"); ZoneId dubaiTimeZone = ZoneId.of("Asia/Dubai"); // Converting Current timezone time to Log Angeles time ZonedDateTime losAngelesDateTime = currentDateTime.withZoneSameInstant(losAngelesTimeZone); // Converting Current timezone time to Dubai time ZonedDateTime dubaiDateTime = currentDateTime.withZoneSameInstant(dubaiTimeZone); // Datetime formatting DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm z"); // Print all 3 dates System.out.println("Current time in IST : " + formatter.format(currentDateTime)); System.out.println("Los Angeles time now : " + formatter.format(losAngelesDateTime)); System.out.println("Dubai time now : " + formatter.format(dubaiDateTime)); // getting the diff b/w two los angeles and dubai times. printDurationBetweenTwoDates(losAngelesDateTime, dubaiDateTime); } private static void printDurationBetweenTwoDates(ZonedDateTime sfoDateTime, ZonedDateTime dubaiDateTime) { Duration d = Duration.between(sfoDateTime, dubaiDateTime); long days = d.get(ChronoUnit.SECONDS); System.out.println("Time Difference between los angeles and dubai : " + days / (60 * 60) + " Hours " + (days % (60 * 60)) / 60 + " Minites"); } }

输出:

Current time in IST : 2020-Dec-01 16:56 IST Los Angeles time now : 2020-Dec-01 03:26 PST Dubai time now : 2020-Dec-01 15:26 GST Time Difference between los angeles and dubai : 0 Hours 0 Minites
    
© www.soinside.com 2019 - 2024. All rights reserved.