簡體   English   中英

JavaScript UTC到本地時間的轉換在IE和Firefox中不起作用,但在Chrome上運行良好

[英]JavaScript UTC to localtime conversion not working in IE & Firefox, but works fine for Chrome

我正面臨一個問題。

我使用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中,我得到的是“無效日期”,而不是我希望看到的時間戳。

請幫忙。

問題是您的Java代碼生成的日期/時間字符串不符合ISO 8601格式 尚未定義JavaScript引擎必須如何處理(因此,一個瀏覽器與另一個瀏覽器不同)。

請參閱如何獲取具有日期,小時和分鍾的ISO 8601格式的當前時刻? 有關如何更改Java代碼以產生使用ISO格式的日期的信息。 您可以將所需的格式(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將在字符串化過程中考慮本地時區。

TL;博士

使用現代的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點。 當我運行該代碼時,我得到:

2018年11月26日16:57:25

不是 UTC 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表示時間軸上的時刻,分辨率為納秒 (最多十進制的九(9)位數字)。

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

這個Instant類是java.time的基本構建塊類。 您可以將OffsetDateTime視為Instant加上ZoneOffset 同樣,您可以將ZonedDateTime視為Instant加上ZoneId

切勿使用LocalDateTime跟蹤時刻,因為它故意缺少時區或UTC偏移量的概念。

ISO 8601

正如Trincot在其正確答案中所述 ,最好將日期時間值作為標准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及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310

您可以直接與數據庫交換java.time對象。 使用與JDBC 4.2或更高版本兼容的JDBC驅動程序 不需要字符串,不需要java.sql.*類。

在哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM