Java 时区转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6567923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Timezone conversion
提问by Senthilnathan
I need to convert from one timezone to another timezone in my project.
我需要在我的项目中从一个时区转换为另一个时区。
I am able to convert from my current timezone to another but not from a different timezone to another.
我能够从我当前的时区转换到另一个时区,但不能从不同的时区转换到另一个时区。
For example I am in India, and I am able to convert from India to US using Date d=new Date();
and assigning it to a calendar object and setting the time zone.
例如,我在印度,我能够使用Date d=new Date();
并将其分配给日历对象并设置时区从印度转换为美国。
However, I cannot do this from different timezone to another timezone. For example, I am in India, but I am having trouble converting timezones from the US to the UK.
但是,我无法从不同时区到另一个时区执行此操作。例如,我在印度,但无法将时区从美国转换为英国。
回答by Jon Skeet
The "default" time zone can be avoided entirely by just setting the time zone appropriately for the Calendar
object. However, I would personally suggest that you use Joda Timeas a far superior API for date and time operations in Java. Amongst other things, time zone conversion is very simple in Joda.
只需为Calendar
对象适当设置时区,就可以完全避免“默认”时区。但是,我个人建议您使用Joda Time作为 Java 中日期和时间操作的卓越 API。除其他外,时区转换在 Joda 中非常简单。
It's not clear what your current code looks like and why you're only able to convert via the default time zone, but in Joda Time you'd just specify the time zone explicitly when creating (say) a DateTime
object, and then use withZone(DateTimeZone zone)
.
目前尚不清楚您当前的代码是什么样的,以及为什么您只能通过默认时区进行转换,但在 Joda Time 中,您只需在创建(例如)DateTime
对象时明确指定时区,然后使用withZone(DateTimeZone zone)
.
If you could tell us more about how you're getting input data, we could give a fuller example.
如果您能告诉我们更多有关您如何获取输入数据的信息,我们可以提供一个更完整的示例。
回答by Srikanth Venkatesh
Some examples
一些例子
Converting Times Between Time Zones
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeZoneExample {
public static void main(String[] args) {
// Create a calendar object and set it time based on the local
// time zone
Calendar localTime = Calendar.getInstance();
localTime.set(Calendar.HOUR, 17);
localTime.set(Calendar.MINUTE, 15);
localTime.set(Calendar.SECOND, 20);
int hour = localTime.get(Calendar.HOUR);
int minute = localTime.get(Calendar.MINUTE);
int second = localTime.get(Calendar.SECOND);
// Print the local time
System.out.printf("Local time : %02d:%02d:%02d\n", hour, minute, second);
// Create a calendar object for representing a Germany time zone. Then we
// wet the time of the calendar with the value of the local time
Calendar germanyTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"));
germanyTime.setTimeInMillis(localTime.getTimeInMillis());
hour = germanyTime.get(Calendar.HOUR);
minute = germanyTime.get(Calendar.MINUTE);
second = germanyTime.get(Calendar.SECOND);
// Print the local time in Germany time zone
System.out.printf("Germany time: %02d:%02d:%02d\n", hour, minute, second);
}
}
回答by Nirmal- thInk beYond
You can do something like this to get the current time in another time zone.
你可以做这样的事情来获取另一个时区的当前时间。
Calendar japanCal = new GregorianCalendar(TimeZone.getTimeZone("Japan"));
japanCal.setTimeInMillis(local.getTimeInMillis());
回答by Rupok
Date date = new Date();
String formatPattern = ....;
SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
TimeZone T1;
TimeZone T2;
// set the Calendar of sdf to timezone T1
sdf.setTimeZone(T1);
System.out.println(sdf.format(date));
// set the Calendar of sdf to timezone T2
sdf.setTimeZone(T2);
System.out.println(sdf.format(date));
// Use the 'calOfT2' instance-methods to get specific info
// about the time-of-day for date 'date' in timezone T2.
Calendar calOfT2 = sdf.getCalendar();
回答by Srijani Ghosh
You can use the following code snippet
您可以使用以下代码片段
String dateString = "14 Jul 2014 00:11:04 CEST";
date = formatter.parse(dateString);
System.out.println(formatter.format(date));
// Set the formatter to use a different timezone - Indochina Time
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("ICT time : "+formatter.format(date));
回答by Basil Bourque
tl;dr
tl;博士
ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" )) // Current moment in a particular time zone.
.withZoneSameInstant( ZoneId.of( "Asia/Kolkata" )) // Same moment adjusted into another time zone.
Details
细节
The java.util.Date class has no time zone assigned?, yet it's toString
implementation confusingly applies the JVM's current default time zone.
java.util.Date 类没有分配时区?,但它的toString
实现令人困惑地应用了 JVM 的当前默认时区。
Avoid java.util.Date & .Calendar
避免 java.util.Date 和 .Calendar
This is one of many reasons to avoid the notoriously troublesome java.util.Date, .Calendar, and SimpleDateFormat classes bundled with Java. Avoid them. Instead use either:
这是避免与 Java 捆绑在一起的臭名昭著的 java.util.Date、.Calendar 和 SimpleDateFormat 类的众多原因之一。避开它们。而是使用:
- The java.time packagebuilt into Java 8 and inspired by Joda-Time.
- Joda-Time
- 该java.time包内置到Java 8和乔达时间的启发。
- 乔达时间
java.time
时间
Java 8 and later has the java.time packagebuilt-in. This package was inspired by Joda-Time. While they share some similarities and class names, they are different; each has features the other lacks. One notable difference is that java.time avoids constructors, instead uses static instantiation methods. Both frameworks are led by the same man, Stephen Colbourne.
Java 8 及更高版本内置了java.time 包。这个包的灵感来自Joda-Time。虽然它们有一些相似之处和类名,但它们是不同的;每个都有另一个缺乏的功能。一个显着的区别是 java.time 避免使用构造函数,而是使用静态实例化方法。这两个框架都由同一个人Stephen Colbourne领导。
Much of the java.time functionality has been back-ported to Java 6 & 7 in the ThreeTen-Backportproject. Further adapted to Android in the ThreeTenABPproject.
在ThreeTen-Backport项目中,大部分 java.time 功能已向后移植到 Java 6 和 7 。在ThreeTenABP项目中进一步适配 Android 。
In the case of this Question, they work in the same fashion. Specify a time zone, and call a now
method to get current moment, then create a new instance based on the old immutable instance to adjust for time zone.
在这个问题的情况下,它们以相同的方式工作。指定一个时区,并调用一个now
方法获取当前时刻,然后根据旧的不可变实例创建一个新实例来调整时区。
Note the two different time zone classes. One is a named time zone including all the rules for Daylight Saving Time and other such anomalies plus an offset from UTC while the other is only the offset.
请注意两个不同的时区类。一个是命名时区,包括夏令时和其他此类异常的所有规则以及与 UTC 的偏移量,而另一个只是偏移量。
ZoneId zoneMontréal = ZoneId.of("America/Montreal");
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );
ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo");
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );
ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );
Joda-Time
乔达时间
Some example code in Joda-Time 2.3 follows. Search StackOveflow for many more examples and much discussion.
Joda-Time 2.3 中的一些示例代码如下。搜索 StackOveflow 以获取更多示例和讨论。
DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime nowLondon = DateTime.now( timeZoneLondon ); // Assign a time zone rather than rely on implicit default time zone.
DateTime nowKolkata = nowLondon.withZone( timeZoneKolkata );
DateTime nowNewYork = nowLondon.withZone( timeZoneNewYork );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC ); // Built-in constant for UTC.
We have four representations of the same moment in the timeline of the Universe.
我们在宇宙的时间线上有四个相同时刻的表示。
?Actually the java.util.Date
class doeshave a time zone buried within its source code. But the class ignores that time zone for most practical purposes. So, as shorthand, it's often said that j.u.Date has no time zone assigned. Confusing? Yes. Avoid the mess that is j.u.Date and go with Joda-Time and/or java.time.
? 实际上,java.util.Date
该类的源代码中确实有一个时区。但是出于大多数实际目的,该类忽略了该时区。因此,作为速记,人们常说 juDate 没有分配时区。令人困惑?是的。避免 juDate 的混乱,并使用 Joda-Time 和/或 java.time。
回答by Glenn
Depends on what you really mean by "converting".
取决于您所说的“转换”的真正含义。
It MAY be as simple as setting the time zone in the FORMATTER, and not mucking with Calendar at all.
它可能就像在 FORMATTER 中设置时区一样简单,而根本不用 Calendar。
Calendar cal = Calendar.getInstance();
TimeZone tzUTC = TimeZone.getTimeZone( "UTC" );
TimeZone tzPST = TimeZone.getTimeZone( "PST8PDT" );
DateFormat dtfmt = new SimpleDateFormat( "EEE, yyyy-MM-dd KK:mm a z" );
dtfmt.setTimeZone( tzUTC );
System.out.println( "UTC: " + dtfmt.format( cal.getTime() ));
dtfmt.setTimeZone( tzPST );
System.out.println( "PST: " + dtfmt.format( cal.getTime() ));
回答by Amro Younes
If you don't want to use Joda, here is a deterministic way using the built in libraries.
如果您不想使用 Joda,这里是使用内置库的确定性方法。
First off I recommend that you force your JVM to default to a timezone. This addresses the issues you might run into as you move your JVM from one machine to another that are set to different timezones but your source data is always a particular timezone. For example, lets say your data is always PDT/PST time zone, but you run on a box that is set to UTC timezone.
首先,我建议您强制 JVM 使用默认时区。这解决了当您将 JVM 从一台机器移动到另一台设置为不同时区但源数据始终是特定时区的机器时可能遇到的问题。例如,假设您的数据始终是 PDT/PST 时区,但您在设置为 UTC 时区的框上运行。
The following code snippet sets the default timezone in my JVM:
以下代码片段在我的 JVM 中设置默认时区:
//You can either pass the JVM a parameter that
//enforces a TZ: java -Duser.timezone=UTC or you can do it
//programatically like this
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone.setDefault(tz);
Now lets say your source date is coming in as PDT/PST but you need to convert it to UTC. These are the steps:
现在假设您的源日期以 PDT/PST 形式出现,但您需要将其转换为 UTC。这些是步骤:
DateFormat dateFormatUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateStrInPDT = "2016-05-19 10:00:00";
Date dateInPDT = dateFormat.parse(dateStrInPDT);
String dateInUtc = dateFormatUtc.format(dateInPDT);
System.out.println("Date In UTC is " + dateInUtc);
The output would be:
输出将是:
Date In UTC is 2016-05-19 17:00:00
回答by Campa
You could use the java.time.ZoneDateTime#ofInstant()
method:
您可以使用以下java.time.ZoneDateTime#ofInstant()
方法:
import java.time.*;
public class TimeZonesConversion {
static ZonedDateTime convert(ZonedDateTime time, ZoneId newTimeZone) {
return ZonedDateTime.ofInstant(
time.toInstant(),
newTimeZone);
};
public static void main(String... args) {
ZonedDateTime mstTime = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("-07"));
ZonedDateTime localTime = convert(mstTime, Clock.systemDefaultZone().getZone());
System.out.println("MST(" + mstTime + ") = " + localTime);
}
}
回答by Αλ?κο?
This is not the answer, but could help someone trying to generate dates with same timezone and apply another timezone's offset. It is useful when your application server is running in one timezone and your database in another.
这不是答案,但可以帮助尝试生成具有相同时区的日期并应用另一个时区的偏移量的人。当您的应用程序服务器在一个时区运行而您的数据库在另一个时区运行时,它很有用。
public static Date toGreekTimezone (Date date) {
ZoneId greek = ZoneId.of(EUROPE_ATHENS);
ZonedDateTime greekDate = ZonedDateTime.ofInstant(date.toInstant(), greek);
ZoneId def = ZoneId.systemDefault();
ZonedDateTime defDate = greekDate.withZoneSameLocal(def);
return Date.from(defDate.toInstant());
}