Java 将日期转换为东部时间-获取日期对象作为输出

Java 将日期转换为东部时间-获取日期对象作为输出,java,date,timezone,date-conversion,java.util.date,Java,Date,Timezone,Date Conversion,Java.util.date,我见过很多将日期从一个时区转换到另一个时区的例子。但它们都以字符串的形式输出。我想要一个日期对象作为输出 我尝试过的方法- 方法1 SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z"); dateTimeFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta")); Date date = new Date(); System.ou

我见过很多将日期从一个时区转换到另一个时区的例子。但它们都以字符串的形式输出。我想要一个日期对象作为输出

我尝试过的方法-

方法1

SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a 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 a z");
timeFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));

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

    } catch (ParseException ex) {
    Logger.getLogger(A.class.getName()).log(Level.SEVERE, null, ex);
}


System.out.println(timeFormat.format(date));
方法2

private static Date shiftTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
        System.out.println(sourceTimeZone.toString());
        System.out.println(targetTimeZone.toString());
        Calendar sourceCalendar = Calendar.getInstance();
        sourceCalendar.setTime(date);
        sourceCalendar.setTimeZone(sourceTimeZone);

        Calendar targetCalendar = Calendar.getInstance();
        for (int field : new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND}) {
            targetCalendar.set(field, sourceCalendar.get(field));
        }
        targetCalendar.setTimeZone(targetTimeZone);

        return targetCalendar.getTime();
    }
方法1将结果作为字符串提供给我

03/22/2018 10:16:57 AM EDT <- instanceOf String
2018年3月22日美国东部夏令时上午10:16:57;博士
或者

避免遗留日期时间类 首先,停止使用旧的日期时间类。他们真是一团糟。被java.time类取代

  • 日期
    替换为
    即时
  • 日历
    分区日期时间
  • SimpleDataFormat
    DateTimeFormatter
    取代
日期::toString欺骗
其次,要了解
Date
有一个非常令人困惑的特性,即在生成字符串时动态应用JVM的当前默认时区
Date
始终表示UTC中的一个时刻。
当日期的值实际上是UTC时,
toString
方法会产生一种错误的错觉,认为日期带有时区。虽然类设计者的意图是好的,但这是一个灾难性的决定,几十年来在无数程序员中造成了无尽的混乱

更糟糕的是:
日期中实际上隐藏着一个时区,但与本次讨论无关。令人困惑对正如我所说,糟糕的设计真是糟糕透顶

Instant
Instant
类替换
Date
更加清晰。
瞬间
表示一个时刻,时间线上的一个点,始终以UTC为单位,分辨率为纳秒

使用
Instant
捕获UTC中的当前时刻。JVM的当前默认时区是不相关的。主机操作系统指定的时区不相关

Instant instant = Instant.now() ;  // Capture the current moment in UTC. 
Date::toString
不同,
Instant::toString
方法讲的是事实。
Instant
始终以UTC为单位,因此
toString
始终报告UTC。以标准ISO 8601格式生成字符串。末尾的
Z
Zulu
的缩写,表示UTC

instant.toString():2018-01-23T12:34:56.123456789Z

关于捕获当前时刻……在Java 8中,当前时刻是以毫秒为单位捕获的,尽管Java.time类可以表示纳秒。在Java9和更高版本中,新的
Clock
实现提供了更细粒度的当前时刻捕获。在macOS Sierra上的Java9.0.4中,我看到了微秒。如今,传统计算机上的硬件时钟无法以超过微秒的精度捕捉当前时刻

ZoneDateTime
要通过特定地区的人们使用的挂钟时间的镜头查看同一时刻,请指定该地区的时区。将
ZoneId
应用于
即时
会生成
zoneDateTime
。概念上:

ZoneDateTime=(即时+区域ID)

代码:

ZoneId z = ZoneId.of( “Pacific/Auckland” ) ;
ZonedDateTime zdt = instant.atZone( z ) ;   // Same moment, same point on the timeline, different wall-clock time. 
适应另一个时区很容易。您可以再次从
即时开始

ZoneId zKolkata = ZoneId.of( “Asia/Kolkata” ) ;
ZonedDateTime zdt = instant.atZone( zKolkata ) ;  
或者您可以调整
ZoneDateTime
对象。time类使用不可变对象。因此,调整不会“改变”(mutate)原始对象,而是生成一个新的不同对象

ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;  // Same moment, same point on the timeline, different wall-clock time. 
您可以跳过使用
即时
。我不建议这样做。程序员应该在UTC中思考、调试、记录、交换数据以及大部分业务逻辑。因此,无论何时开始使用日期-时间值的工作,
Instant
都应该是您的必修课

ZonedDateTime zdtNewYork = ZonedDateTime.now( ZoneId.of( "America/New_York" ) ) ;
ZonedDateTime::toString
方法通过在方括号中添加时区名称,明智地扩展了ISO 8601标准

String output = zdtNewYork.toString() ;
2018-01-23T07:34:56.123456789-05:00[美国/纽约]


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • ,及以后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类
    • 对于早期的Android(tl;dr 或者

      避免遗留日期时间类 首先,停止使用遗留的日期时间类。它们是一堆糟糕透顶的垃圾。被java.time类所取代

      • 日期
        替换为
        即时
      • 日历
        分区日期时间
      • SimpleDataFormat
        DateTimeFormatter
        取代
      日期::toString欺骗
      其次,要了解
      Date
      有一个非常令人困惑的特性,即在生成字符串时动态应用JVM当前的默认时区。
      Date
      始终代表UTC中的一个时刻。
      当ac实际上,它的价值是UTC。虽然类设计者的初衷是好的,但这是一个灾难性的决定,几十年来在无数程序员中造成了无尽的混乱

      更糟糕的是,
      Dat中实际上隐藏着一个时区
      
      ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;  // Same moment, same point on the timeline, different wall-clock time. 
      
      ZonedDateTime zdtNewYork = ZonedDateTime.now( ZoneId.of( "America/New_York" ) ) ;
      
      String output = zdtNewYork.toString() ;