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

Har*_*r S 1 timezone datetime android simpledateformat

这是我的示例代码返回相同的日期,我正在尝试将 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!!))
Run Code Online (Sandbox Code Playgroud)

Bas*_*que 5

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 Code Online (Sandbox Code Playgroud)

查看此代码在 IdeOne.com 上实时运行

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

细节

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

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

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 Code Online (Sandbox Code Playgroud)

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

切勿使用 2-4 伪区域代码,例如MSTEST。这些都不是标准化的。这些甚至都不是独一无二的!使用实时区名称,格式Continent/Region(与像一些例外America/Indiana/IndianapolisArctic/Longyearbyen等等)。

String input = "2021-03-05T14:14:27.99" ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
Run Code Online (Sandbox Code Playgroud)

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

ZoneId zoneDenver = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdtDenver = ldt.atZone( zoneDenver ) ;
Run Code Online (Sandbox Code Playgroud)

Java 中的日期时间类型表,现代和传统

修复已发布的数据馈送

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

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

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

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

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

2021-03-05T21:14:27.990Z

这两个选项都在 IdeOne.com 上进行了现场演示

ZoneId zoneNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdtDenver.withZoneSameInstant( zoneNewYork ) ;
Run Code Online (Sandbox Code Playgroud)

… 和 …

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

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

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

现在处于维护模式Joda-Time项目建议迁移到java.time类。

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

从哪里获得 java.time 类?

在此处输入图片说明