时区转换

Sen*_*han 41 java timezone datetime

我需要在我的项目中从一个时区转换到另一个时区.

我可以从我当前的时区转换到另一个时区,但不能从不同的时区转换到另一个时区.

例如,我在印度,我能够使用Date d=new Date();并将其分配给日历对象并设置时区,从印度转换为美国.

但是,我不能从不同的时区到另一个时区这样做.例如,我在印度,但我无法将时区从美国转换到英国.

Bas*_*que 46

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. 
Run Code Online (Sandbox Code Playgroud)

细节

java.util.Date类没有分配时区,但它的toString实现混淆地应用了JVM的当前默认时区.

避免使用java.util.Date和.Calendar

这是避免与Java捆绑的臭名昭着的java.util.Date,.Calendar和SimpleDateFormat类的众多原因之一.避免他们.而是使用:

java.time

Java 8及更高版本内置了java.time包.这个包的灵感来自Joda-Time.虽然它们有一些相似之处和类名,但它们是不同的; 每个都有其他缺乏的功能.一个值得注意的区别是java.time避免使用构造函数,而是使用静态实例化方法.两个框架都由同一个人Stephen Colbourne领导.

许多java.time功能已经在ThreeTen-Backport项目中反向移植到Java 6和7 .在ThreeTenABP项目中进一步适应Android .

就本课题而言,它们的工作方式相同.指定时区,并调用now方法获取当前时刻,然后基于旧的不可变实例创建新实例以调整时区.

请注意两个不同的时区类.一个是命名时区,包括夏令时的所有规则和其他此类异常加上与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 );
Run Code Online (Sandbox Code Playgroud)

乔达时间

下面是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.
Run Code Online (Sandbox Code Playgroud)

我们在宇宙的时间轴上有四个相同时刻的表示.


实际上,java.util.Date该类确实其源代码中埋藏了一个时区.但是为了大多数实际目的,该课程忽略了该时区.因此,作为速记,通常会说juDate没有分配时区.混乱?是.避免混乱是juDate并使用Joda-Time和/或java.time.


小智 38

一些例子

在时区之间转换时间

转换时区之间的时间

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Rup*_*pok 7

    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();
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 5

只需为Calendar对象设置适当的时区,即可完全避免"默认"时区.但是,我个人建议您使用Joda Time作为Java中日期和时间操作的优秀API.除此之外,Joda的时区转换非常简单.

目前尚不清楚当前代码是什么样的以及为什么你只能通过默认时区进行转换,但在Joda Time中你只需要在创建(比如说)DateTime对象时明确指定时区,然后再使用withZone(DateTimeZone zone).

如果您可以告诉我们更多关于您如何获取输入数据的信息,我们可以提供更全面的示例.