我的服务器向我发送格式为“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)));
答案 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.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
使用 java.time
(现代日期时间 API)的解决方案:
您可以创建一个 ZonedDateTime
实例,该实例旨在在 DST 转换时自动调整时区偏移。
如果您需要时区偏移量而不是时区名称,您可以使用 ZonedDateTime#toOffsetDateTime
将 ZonedDateTime
转换为 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
从 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 desugaring 和 How to use ThreeTenABP in Android Project。