我遇到了一个问题。
我正在使用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中,我得到的是“无效日期”,而不是我希望看到的时间戳。
请帮助。
答案 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)
使用现代的 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 类早已取代了这些日期时间类。
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偏移量的概念。
正如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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。