在Java ME中将“America / Los Angeles”时区转换为“PST”或“PDT”

时间:2011-02-01 23:31:58

标签: java blackberry date java-me timezone

我的服务器向我发送格式为“America / Los Angeles”的时区。在客户端,我有时间需要在该时区显示。答案将是“PST”或“PDT”,具体取决于给定时间的夏令时。我该如何进行转换?

我正在使用Java ME(Blackberry 4.7,准确无误),所以我不能使用Joda Time。

我需要在很多日期(但只有一个时区)快速进行此计算,所以我不能让服务器向我发送偏移量,因为偏移量可能会根据日期而改变。

编辑:让我重申一下这个问题,因为似乎有些混乱。我获得了zoneinfo名称和日期。我想知道那个时区GMT在该时区的偏移量。答案将根据夏令时而有所不同。

作为一个额外的奖励,我想让TLA向用户展示(即“PST”或“PDT”),但这是次要的。

解决方案:我将在此总结解决方案,因为下面的答案并不十分明确。这基本上是我需要的,在J2ME中:

TimeZone zone = TimeZone.getTimeZone("America/Los_Angeles");
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(zone);

calendar.setTime(new Date(2011, 1, 1, 12, 0, 0));      
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));
calendar.setTime(new Date(2011, 6, 1, 12, 0, 0));
System.out.println(zone.getOffset(1, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.DAY_OF_WEEK), calendar.get(Calendar.MILLISECOND)));

3 个答案:

答案 0 :(得分:6)

可能这就是你想要的。这可以在我的机器上使用标准java。

        Calendar calendar = Calendar.getInstance();       
        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
        calendar.setTimeZone(tz);
         System.out.println("Offset from UTC="+tz.getOffset(calendar.getTimeInMillis())/(60*60*1000)); //prints -8
        System.out.println(tz.getDisplayName(Boolean.TRUE, 0)); //prints PDT
        System.out.println(tz.getDisplayName(Boolean.TRUE, 1)); //prints Pacific Daylight Time
        System.out.println(tz.getDisplayName(Boolean.FALSE, 0));//prints PST
        System.out.println(tz.getDisplayName(Boolean.FALSE, 1));//prints Pacific Standard Time  

更新:OP表示以上内容对j2ME无效。在谷歌搜索后,我发现here getOffset()实际上是j2me中的getRawOffset()。但是,它看起来不像是supposrts displayName。我认为您唯一的选择是使用getAvailableIds()来查看ID。

答案 1 :(得分:1)

J2ME不支持TimeZone.getTimeZone(id)吗?这基本上是你想要的,以便获得时区偏移等。我希望J2ME支持zoneinfo区域名称。

答案 2 :(得分:1)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

使用 java.time(现代日期时间 API)的解决方案:

您可以创建一个 ZonedDateTime 实例,该实例旨在在 DST 转换时自动调整时区偏移。

如果您需要时区偏移量而不是时区名称,您可以使用 ZonedDateTime#toOffsetDateTimeZonedDateTime 转换为 OffsetDateTime

演示:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZoneId zoneIdLosAngeles = ZoneId.of("America/Los_Angeles");
        ZonedDateTime zdtNowLosAngeles = ZonedDateTime.now(zoneIdLosAngeles);
        System.out.println(zdtNowLosAngeles);

        // With zone offset but without time zone name
        OffsetDateTime odtNowLosAngeles = zdtNowLosAngeles.toOffsetDateTime();
        System.out.println(odtNowLosAngeles);

        // ################ A winter date-time ################
        ZonedDateTime zdtLosAngelesWinter = ZonedDateTime
                .of(LocalDateTime.of(LocalDate.of(2021, 11, 20), LocalTime.of(10, 20)), zoneIdLosAngeles);
        System.out.println(zdtLosAngelesWinter); // 2021-11-20T10:20-08:00[America/Los_Angeles]
        System.out.println(zdtLosAngelesWinter.toOffsetDateTime()); // 2021-11-20T10:20-08:00
    }
}

样本运行的输出:

2021-07-18T04:09:57.993440-07:00[America/Los_Angeles]
2021-07-18T04:09:57.993440-07:00
2021-11-20T10:20-08:00[America/Los_Angeles]
2021-11-20T10:20-08:00

ONLINE DEMO

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project