使用Java中的各种Calendar TimeZone(不使用Joda Time)

时间:2013-10-30 20:56:00

标签: java calendar timezone

我一直在寻找一种基于用户输入在各个时区获得当前时间的方法。我知道我可以使用Joda Time!但这是唯一的方法吗?

Java中没有这样的选项吗?我尝试了以下代码,为所有3个sysout提供相同的输出。

Calendar pst = Calendar.getInstance(TimeZone.getTimeZone("PST"));
System.out.println("PST " + pst.getTime());
Calendar ist = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
System.out.println("IST " + ist.getTime());
Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("Etc/UTC"));
System.out.println("UCT " + utc.getTime());

我在这里缺少什么才能获得其他时区的当前时间?

3 个答案:

答案 0 :(得分:6)

是的,这会在每种情况下(或相隔毫秒)显示相同的值,因为三个日历都引用相同的及时(尽管执行时间)并且全部一个java.util.Date代表。这是Calendar.getTime()的结果。

但是,Calendar本身确实了解时区,并且会在您使用Calendar.get等时反映出来。它还会 在使用SimpleDateFormat时使用,您可以在其中指定特定时区。

// Specify whatever format you want - bear in mind different locales etc
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
format.setTimeZone(calendar.getTimeZone());
String text = format.format(calendar.getTime());

目前还不清楚你要做的是什么,但基本上你需要知道哪些类型是时区感知的,哪些类型不是。了解java.util.Date没有格式,日历系统或时区非常重要:它的只是毫秒数自Unix时代以来。

答案 1 :(得分:1)

正如Jon指出的那样,方法getTime()正在返回一个java.util.Date对象,该对象只是一个毫秒值而不是时区感知。

如果您只是打印时间,那么您可以使用日历并手动获取您想要的字段

System.out.println(utc.get(Calendar.HOUR_OF_DAY) + ":" + utc.get(Calendar.MINUTE))

这需要一些格式化一分钟< 10显示0

答案 2 :(得分:0)

java.time

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

另外,下面引用的是来自 home page of Joda-Time 的通知:

<块引用>

请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。

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

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        System.out.println(now);

        ZonedDateTime zdtLos = now.atZone(ZoneId.of("America/Los_Angeles"));
        ZonedDateTime zdtIndia = now.atZone(ZoneId.of("Asia/Kolkata"));
        ZonedDateTime zdtUtc = now.atZone(ZoneOffset.UTC);

        System.out.println(zdtLos);
        System.out.println(zdtIndia);
        System.out.println(zdtUtc);
    }
}

样本运行的输出:

2021-07-26T12:39:17.413671-07:00[America/Los_Angeles]
2021-07-27T01:09:17.413671+05:30[Asia/Kolkata]
2021-07-26T19:39:17.413671Z

ONLINE DEMO

Instant 表示时间线上的瞬时点,通常以 UTC 时间表示。输出中的 Z 是零时区偏移的 timezone designator。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移为 +00:00 小时)。

出于任何原因,如果您需要将 Instant 的这个对象转换为 java.util.Date 的对象,您可以这样做:

Date date = Date.from(instant);

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

切勿使用 3 个字母的缩写时区 ID

以下是 documentation page of TimeZone 的摘录:

<块引用>

为了与 JDK 1.1.x 兼容,其他一些三字母时区 还支持 ID(例如“PST”、“CTT”、“AST”)。然而,他们的 不推荐使用,因为相同的缩写经常用于 多个时区(例如,“CST”可以是美国的“Central 标准时间”和“中国标准时间”),Java平台可以 然后只识别其中一个。


* 出于任何原因,如果您必须坚持使用 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