如何将日期时间从 MST 转换为 EST?

问题描述

这是我返回相同日期的示例代码,我正在尝试将 MST 日期和时间转换为 EST 日期和时间,谁能给我一个建议。 它应该支持android os 4.4.4到11。

var input ="2021-03-05T14:14:27.99"

        val formatMST: DateFormat =  SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH)
                    formatMST.timeZone = TimeZone.getTimeZone("MST")

        val formatEST: DateFormat =  SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH)
                    formatEST.timeZone = TimeZone.getTimeZone("EST")

        val dateFormat: DateFormat =  SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ENGLISH)

        var date = dateFormat.parse(input.replace("T"," "))
            date = dateFormat.parse(formatMST.format(date!!))
Log.d("mst_","input:$input   ::  " + formatEST.format(date!!))

解决方法

tl;博士

LocalDateTime                                             // Represent a date with time-of-day but lacking the context of a time zone or offset-from-UTC.
.parse( "2021-03-05T14:14:27.99" )                        // Parse text in standard ISO 8601 format.
.atZone( ZoneId.of( "America/Denver" ) )                  // Place that date with time-of-day into the context of a time zone. Determines a moment. Returns a `ZonedDateTime` object.
.withZoneSameInstant( ZoneId.of( "America/New_York" ) )   // Adjust into anther time zone. Same moment,same point on the timeline,different wall-clock time. Returns another `ZonedDateTime` object,per immutable objects pattern.
.format(                                                  // Generate text representing the value without our `ZonedDateTime` object.
    DateTimeFormatter
    .ofLocalizedDateTime( FormatStyle.FULL )              // Automatically localize.
    .withLocale( Locale.US )                              // Returns a `DateTimeFormatter` object. 
)                                                         // Returns a `String` object.

请参阅此代码 run live at IdeOne.com

东部标准时间 2021 年 3 月 5 日,星期五,下午 4:14:27

详情

切勿使用糟糕的 java.util.DateCalendarSimpleDateFormat 类。这些遗留类在多年前被 JSR 310 中定义的现代 java.time 类所取代。

将您的输入字符串解析为 LocalDateTime,因为它缺少时区或UTC 偏移量的指示符。文本格式符合ISO 8601标准格式,无需指定格式。

String input = "2021-03-05T14:14:27.99" ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;

如果您确定该值旨在表示在特定时区中看到的时刻,请应用 ZoneId 以获得 ZonedDateTime

切勿使用 2-4 伪区域代码,例如 MSTEST。这些都不是标准化的。这些甚至都不是独一无二的!以 Continent/Region 的格式使用 real time zone namesAmerica/Indiana/IndianapolisArctic/Longyearbyen 等除外)。

ZoneId zoneDenver = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdtDenver = ldt.atZone( zoneDenver ) ;

调整到另一个时区。同一时刻,时间线上的同一点,不同的挂钟时间。

ZoneId zoneNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdtDenver.withZoneSameInstant( zoneNewYork ) ;

Table of date-time types in Java,both modern and legacy

修复已发布的数据 Feed

如果您的输入字符串确实是代表山区时区中的某个时刻,那么您的数据馈送已损坏。重要数据丢失。

我建议您教育该日期的发布者将这些有价值的信息包含在数据中。

一种选择是使用 ZonedDateTime#toString 所使用的 ISO 8601 格式的扩展,其中,除了存在偏移量外,时区名称附加在方括号中。

2021-03-05T14:14:27.990-07:00[美国/丹佛]

或者,数据发布者可以在生成文本之前调整为 UTC(零时分秒的偏移量)。在 ISO 8601 格式中,末尾的 Z 表示偏移为零,按照航空/军事传统发音为“Zulu”。一般来说,这是最好的方法。除非业务规则另有要求,否则程序员、测试人员和管理员通常应该使用 UTC 进行思考和工作。

2021-03-05T21:14:27.990Z

两个选项都是 demonstrated live at IdeOne.com

System.out.println(
    LocalDateTime
    .parse( "2021-03-05T14:14:27.99" )
    .atZone( ZoneId.of( "America/Denver" ) )
    .toString()
);

……和……

System.out.println(
    LocalDateTime
    .parse( "2021-03-05T14:14:27.99" )
    .atZone( ZoneId.of( "America/Denver" ) )
    .toInstant()
    .toString()
);

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为 JSR 310

现在位于 Joda-Timemaintenance mode 项目建议迁移到 java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC driver 或更高版本的 JDBC 4.2。不需要字符串,不需要 java.sql.* 类。 Hibernate 5 和 JPA 2.2 支持 java.time

从哪里获取 java.time 类?

enter image description here

,
try {
            val instance = Calendar.getInstance()
            val timeZone: TimeZone = TimeZone.getTimeZone("America/Denver") // from MST or America/Denver
            // set time zone
            instance.timeZone = timeZone

            // set the input
            instance.set(Calendar.HOUR,2) //hour
            instance.set(Calendar.MINUTE,14) //minute
            instance.set(Calendar.YEAR,2021) //year
            instance.set(Calendar.MONTH,3) //month
            instance.set(Calendar.DAY_OF_MONTH,5) //day

            val dateFormat = SimpleDateFormat("dd MMM yyyy HH:mm",Locale.US)
            dateFormat.timeZone = TimeZone.getTimeZone("America/New_York")
            Log.d("expire01","output to convert date time from MST to EST : ${dateFormat.format(instance.time)}")
        }
        catch (e: Exception){
            Log.d("expire01","catch : ${e.message}")
        }

结果

// output to convert date time from MST to EST : 05 Apr 2021 04:14

这是解决方案之一