JavaScript UTC到本地时间的转换在IE和Firefox中不起作用,但在Chrome上运行良好

时间:2018-11-26 14:49:01

标签: javascript

我遇到了一个问题。

我正在使用Java代码在服务器中节省UTC时间:

DateFormat timeFormat = new SimpleDateFormat("dd-MMMM-yy HH:mm:ss");

我坚持这个->

time = timeFormat.format(new Date()).toString()

这是UTC时间。

现在,在浏览器中显示它时,我将其转换为本地时间:

var date = new Date(time);

convertToLocal(date).toLocaleString();

function convertToLocal(date) {
    var newDate = new Date(date.getTime() +date.getTimezoneOffset()*60*1000);

    var offset = date.getTimezoneOffset() / 60;
    var hours = date.getHours();

    newDate.setHours(hours - offset);

    return newDate;
}

console.log("Time : " + convertToLocal(date).toLocaleString())

这在Chrome浏览器中工作正常,但在Firefox和IE中,我得到的是“无效日期”,而不是我希望看到的时间戳。

请帮助。

2 个答案:

答案 0 :(得分:3)

问题是您的Java代码生成的日期/时间字符串不符合 ISO 8601 format。 JavaScript引擎必须如何处理它尚未定义(因此,从一个浏览器到另一个浏览器是不同的)。

有关如何更改Java代码以产生使用ISO格式的日期的信息,请参见How to get current moment in ISO 8601 format with date, hour, and minute?。您只需将所需的格式(ISO)传递给SimpleDateFormat并将其配置为UTC:

DateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

该输出应类似于2018-11-26T19:41:48Z(接受此格式的多个变体)。注意“ T”和终止“ Z”(对于UTC)。

完成后,JavaScript会正确解释UTC时区中指定的日期/时间,然后您只需要在JavaScript中执行以下操作,而无需显式添加时区差:

console.log("Time : " + date.toLocaleString())

JavaScript,它将在字符串化过程中考虑本地时区。

答案 1 :(得分:0)

tl; dr

使用现代的 java.time 类,而不是可怕的旧类。

以标准ISO 8601格式发送字符串。

Instant
.now()
.truncatedTo(
    ChronoUnit.SECONDS
)
.toString()
  

Instant.now()。toString():2018-11-27T00:57:25Z

代码有误

  

这是UTC时间。

否,不正确。您不是在UTC中录制时刻。

DateFormat timeFormat = new SimpleDateFormat("dd-MMMM-yy HH:mm:ss");
String time = timeFormat.format(new Date()).toString() ;

您确实在SimpleDateFormat类中指定了时区。默认情况下,该类隐式应用JVM的当前默认时区。因此,生成的字符串将在运行时变化。

例如,在我当前的默认时区America/Los_Angeles中,这不是下午5点。当我运行该代码时,我得到:

  

18年11月26日16:57:25

不是 UTC。格林尼治标准时间是几个小时后,即明天午夜之后,如下所示:

  

Instant.now()。toString():2018-11-27T00:57:25.389849Z

如果要整秒,请致电truncatedTo。将小数秒降低。

  

Instant.now()。truncatedTo(ChronoUnit.SECONDS).toString():2018-11-27T00:57:25Z

java.time

您使用的是可怕的旧日期时间类,而现代的 java.time 类早已取代了这些日期时间类。

Instant

Instant类表示UTC中时间轴上的时刻,分辨率为nanoseconds(十进制小数的九(9)位)。

Instant nowInUtc = Instant.now() ;  // Capture the current moment in UTC.

这个Instant类是java.time的基本构建块类。您可以将OffsetDateTime视为Instant加上ZoneOffset。同样,您可以将ZonedDateTime视为Instant加上ZoneId

切勿使用LocalDateTime来跟踪时刻,因为它故意缺少时区或UTC偏移量的概念。

ISO 8601

正如his correct Answer中所述的小结,最好将日期时间值作为标准ISO 8601格式的文本进行交换。

在UTC中,一会儿是

  • 2018-11-27T00:57:25.389849Z,其中Z的末尾表示UTC,并发音为“ Zulu”。
  • 2018-11-27T00:57:25.389849+00:00,其中+00:00表示与UTC的时差为零小时,分钟,秒或UTC本身。

关于 java.time

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

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

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

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

相关问题