问题描述
这是我返回相同日期的示例代码,我正在尝试将 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.Date
、Calendar
和 SimpleDateFormat
类。这些遗留类在多年前被 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 伪区域代码,例如 MST
和 EST
。这些都不是标准化的。这些甚至都不是独一无二的!以 Continent/Region
的格式使用 real time zone names(America/Indiana/Indianapolis
、Arctic/Longyearbyen
等除外)。
ZoneId zoneDenver = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdtDenver = ldt.atZone( zoneDenver ) ;
调整到另一个时区。同一时刻,时间线上的同一点,不同的挂钟时间。
ZoneId zoneNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdtDenver.withZoneSameInstant( zoneNewYork ) ;
修复已发布的数据 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.Date
、Calendar
和 SimpleDateFormat
。
要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为 JSR 310。
现在位于 Joda-Time 的 maintenance mode 项目建议迁移到 java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC driver 或更高版本的 JDBC 4.2。不需要字符串,不需要 java.sql.*
类。 Hibernate 5 和 JPA 2.2 支持 java.time。
从哪里获取 java.time 类?
-
Java SE 8、Java SE 9、Java SE 10、Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。
- Java 9 带来了一些小功能和修复。
-
Java SE 6 和 Java SE 7
- 大部分 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。
-
Android
- 更高版本的 Android (26+) 捆绑了 java.time 类的实现。
- 对于早期的 Android (API desugaring 的进程带来了最初未内置于 Android 中的 subset of the java.time 功能。
- 如果脱糖不能满足您的需求,ThreeTenABP 项目会将 ThreeTen-Backport(上文提到的)适配到 Android。见How to use ThreeTenABP…。
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
这是解决方案之一