0

我在 IST 时间中有一个 Java 日期字段。我想将其转换为 EST 时间,并且输出应仅为日期类型。我可以使用以下代码完成相同的操作:-

SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
dateTimeFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
Date date = new Date();
DateFormat timeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
timeFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String estTime = timeFormat.format(date);
date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ENGLISH).parse(estTime);

上述代码的问题在于,虽然日期转换为 EST 时间,但时区仍显示为 IST 而不是 EST。日期的其余部分转换得非常好。有没有办法在日期字段中将时区明确设置为 EST。对此的任何帮助将不胜感激。

-Subhadeep

4

4 回答 4

1

该类Date与时区无关。基本上,它始终基于 GMT,尽管在打印时它使用当前系统时区来调整它。

但是,Calendar是特定于时区的。请参阅Calendar.setTimeZone()

考虑:

   Calendar cal = new GregorianCalendar();
   cal.setTimeZone(TimeZone.getTimeZone("America/New_York"));
   cal.setTime(new Date());
于 2013-03-18T12:50:49.840 回答
1

java.time

旧的日期时间 API(java.util日期时间类型及其格式类型SimpleDateFormat等)已过时且容易出错。建议完全停止使用它并切换到java.time现代日期时间 API *

使用java.time现代 API 的解决方案:

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

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

        ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Calcutta"));
        ZonedDateTime zdtNewYork = instant.atZone(ZoneId.of("America/New_York"));

        System.out.println(zdtIndia);
        System.out.println(zdtNewYork);
    }
}

输出:

2021-05-19T21:08:54.241341Z
2021-05-20T02:38:54.241341+05:30[Asia/Calcutta]
2021-05-19T17:08:54.241341-04:00[America/New_York]

Instant表示时间线上的一个瞬时点。Z输出中的 是零时区偏移的时区指示符。它代表 Zulu 并指定Etc/UTC时区(时区偏移量为+00:00小时)。

Trail: Date Time了解更多关于java.time现代日期时间 API *的信息。

使用旧版 API 的解决方案:

java.util.Date对象不是像现代日期时间类型那样的真实日期时间对象;相反,它表示自称为“纪元” January 1, 1970, 00:00:00 GMT(或 UTC)的标准基准时间以来的毫秒数。当您打印 的对象时java.util.Date,其toString方法会返回 JVM 时区中的日期时间,根据此毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为SimpleDateFormat并从中获取格式化字符串。

演示:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS[zzzzz]");

        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
        String dtIndia = sdf.format(date);

        sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        String dtNewYork = sdf.format(date);

        System.out.println(dtIndia);
        System.out.println(dtNewYork);
    }
}

输出:

Wed May 19 22:16:08 BST 2021
2021-05-20T02:46:08.024[India Standard Time]
2021-05-19T17:16:08.024[Eastern Daylight Time]

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

于 2021-05-19T21:18:38.790 回答
0

你应该在你的模式中添加z时区SimpleDateFormat模式吗?

所以,应该是DateFormat timeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z")。我像这样更改了您的代码:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
    dateTimeFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
    Date date = new Date();

    System.out.println(dateTimeFormat.format(date)); // this print IST Timezone

    DateFormat timeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
    timeFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));

    String estTime = timeFormat.format(date);
    date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z", Locale.ENGLISH).parse(estTime);

    System.out.println(timeFormat.format(date)); // this print EDT Timezone currently (on March)
}

在最后的打印语句中,当前日期格式使用EDT 时区(东部夏令时间)打印。也许是因为这个

于 2013-03-18T13:10:18.103 回答
0

John B的正确答案解释说 java.util.Date 似乎有一个时区,但没有。它的toString方法在生成字符串表示时应用您的 JVM 的默认时区。

这是避免与 Java 捆绑在一起的 java.util.Date 和 .Calendar 类的众多原因之一。避开他们。而是使用Joda-Time或 Java 8 中内置的 java.time 包(受 JSR 310 定义的 Joda-Time 启发)。

这是 Joda-Time 2.3 中的一些示例代码。

String input = "01/02/2014 12:34:56";
DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "MM/dd/yyyy HH:mm:ss" );
DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = formatterInput.withZone( timeZoneIndia ).parseDateTime( input );

DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = dateTimeIndia.withZone( timeZoneNewYork );

DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC );

转储到控制台...</p>

System.out.println( "input: " + input );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
System.out.println( "dateTimeUtc: " + dateTimeUtc );

运行时……</p>

input: 01/02/2014 12:34:56
dateTimeIndia: 2014-01-02T12:34:56.000+05:30
dateTimeNewYork: 2014-01-02T02:04:56.000-05:00
dateTimeUtc: 2014-01-02T07:04:56.000Z
于 2014-03-08T08:36:52.420 回答