【问题标题】:Converting the "America/Los Angeles" time zone to "PST" or "PDT" in Java ME在 Java ME 中将“美国/洛杉矶”时区转换为“PST”或“PDT”
【发布时间】:2011-02-01 23:31:58
【问题描述】:

我的服务器向我发送“美国/洛杉矶”格式的时区。在客户端上,我需要在该时区显示时间。答案将是“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)));

【问题讨论】:

  • 由于this answer,'Amrica/Los_angeles' 和 'PDT' 有相等的偏移量!

标签: java blackberry date java-me timezone


【解决方案1】:

也许这就是你想要的。这适用于我使用标准 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()。但是,它看起来并不支持 displayName。我认为您唯一的选择是使用getAvailableIds() 来检查ID。

【讨论】:

  • 那很好,但是 J2ME 没有 TimeZone.getDisplayName() :-(
  • 我也为你添加了偏移量。
  • 是否支持getOffset()?
  • 我之前的评论很愚蠢,所以我删除了它。 getRawOffset() 不能工作,因为它不需要日期。 J2ME 只有长格式 getOffset(),我必须使用上面添加的代码。
【解决方案2】:

java.time

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

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

您可以创建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 了解有关现代日期时间 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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 这给了我 ID 为“America/Los Angeles”的时区,无论日期如何,它都完全等于 PST。
    • BlackBerry 的 TimeZone 实现支持 zoneinfo 名称。我认为 OP 的问题在于他收到的是时区缩写,而不是 zoneinfo 名称。如果 BlackBerry 无法识别缩写,则默认为 GMT。不幸的是,BB模型通常不知道很多缩写。您可以使用TimeZone.getAvailableIDs() 查看特定平台支持的内容。
    • @Ted:问题说 OP 正在获取 zoneinfo 名称。我还是有点迷茫……
    • @Marvin:您如何确定“America/Los Angeles”完全等于 PST?这会让我感到惊讶。
    • 你说得对,它们是不同的。我错了。感谢您指出这一点!
    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2016-11-21
    • 2017-06-19
    相关资源
    最近更新 更多