pos機(jī)時間不對

 新聞資訊3  |   2023-08-13 12:12  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于pos機(jī)時間不對,改變JVM默認(rèn)時區(qū)是否影響log4j打印日志中的日期時間的知識,也有很多人為大家解答關(guān)于pos機(jī)時間不對的問題,今天pos機(jī)之家(www.nxzs9ef.cn)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機(jī)時間不對

pos機(jī)時間不對

引言

在【JVM & MySQL時區(qū)配置問題-兩行代碼讓我們一幫子人熬了一個通宵】描述了由于代碼BUG導(dǎo)致存儲到數(shù)據(jù)庫的時間比正常時間少八小時的案例。當(dāng)時分析的時候發(fā)現(xiàn)log4j打印的日志文件中日期時間都是正確的,下面對這個問題進(jìn)行下驗證和分析。

測試環(huán)境Java version

java version "1.8.0_341"Java(TM) SE Runtime Environment (build 1.8.0_341-b10)Java HotSpot(TM) Client VM (build 25.341-b10, mixed mode, sharing)pom

<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.19.0</version></dependency><dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.19.0</version></dependency>測試代碼&配置

import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import java.util.TimeZone;public class Log4jTimezoneTest { private static Logger LOGGER = LogManager.getLogger(); public static void main(String[] args){ // JVM默認(rèn)時區(qū):東八區(qū) LOGGER.info("Hello World!"); // 模擬應(yīng)用問題場景:改變JVM默認(rèn)時區(qū) TimeZone.setDefault(TimeZone.getTimeZone("GMT")); LOGGER.info("Hello World!"); }}

<?xml version="1.0" encoding="UTF-8"?><Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <patternLayout pattern="%d [%t] %-5level %c:%M(%L) - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="Console"/> </Root> </Loggers></Configuration>分析過程FixedDateFormat

一路跟蹤代碼,最終格式化日期時間的類是:org.apache.logging.log4j.core.util.datetime.FixedDateFormat。

基本使用

import org.apache.logging.log4j.core.util.datetime.FixedDateFormat;import java.util.TimeZone;public class TimeZoneTest { public static void main(String[] args){ long time = System.currentTimeMillis(); // 默認(rèn)時區(qū)為東八區(qū) FixedDateFormat fixedDateFormat = FixedDateFormat.createIfSupported(null); String str = fixedDateFormat.format(time); System.out.println(str); // 改變默認(rèn)時區(qū)為零時區(qū) TimeZone.setDefault(TimeZone.getTimeZone("GMT")); fixedDateFormat = FixedDateFormat.createIfSupported(null); str = fixedDateFormat.format(time); System.out.println(str); }}初始化

創(chuàng)建FixedDateFormat實例

FixedDateFormat在初始化的時候配置了時區(qū)信息。

FixedFormat

枚舉類型,定義了日期時間的各種樣式。下面以FixedFormat.ISO8601為例解釋下各個字段的含義:

ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS", "yyyy-MM-dd'T'", 2, ':', 1, ',', 1, 3, null)

字段

字段示例

說明

pattern

yyyy-MM-dd’T’HH:mm:ss,SSS

日期時間格式

datePattern

yyyy-MM-dd’T’

日期格式

escapeCount

2

pattern中T兩邊單引號的個數(shù)

timeSeparator

:

小時與分鐘、分鐘與秒之間的分隔符

timeSepLength

1

timeSeparator字符長度

millisSeparator

,

秒與毫秒之間的分隔符

millisSepLength

1

millisSeparator字符長度

secondFractionDigits

3

millisSeparator后面時間字符的長度

timeZoneFormat

null,其他示例:+08、+0800、+08:00

日期時間格式中是否顯示時區(qū)信息,類型為FixedTimeZoneFormat,三種樣式:HH、HHMM、HHCMM

format

格式化日期流程

1.初始化char數(shù)組

// double size for locales with lengthy DateFormatSymbolsfinal char[] result = new char[length << 1];

char數(shù)組用于存放格式化后的pattern數(shù)據(jù)。

2.計算從當(dāng)天午夜開始的毫秒數(shù)

midnightToday:當(dāng)天午夜時間戳,默認(rèn)值為0;midnightTomorrow:明天午夜時間戳,默認(rèn)值為0;這里是個緩存的邏輯:如果待格式化的時間戳在midnightToday和midnightTomorrow之間,則直接返回:【待格式化時間戳】減去【midnightToday】;否則執(zhí)行下面計算并緩存相應(yīng)的值:

2.2.1格式化日期并緩存

對于一個時間戳來說從零點(diǎn)到24點(diǎn)之間,日期部分是不變的,所以解析并緩存起來。

private void updateCachedDate(final long now) { if (fastDateFormat != null) { final StringBuilder result = fastDateFormat.format(now, new StringBuilder()); cachedDate = result.toString().toCharArray(); dateLength = result.length(); }}2.2.2計算當(dāng)前午夜時間戳

midnightToday = calcMidnightMillis(now, 0);

計算午夜時間戳

2.2.3計算明天午夜時間戳

與2.2.2不同的是addDays是1。

midnightTomorrow = calcMidnightMillis(now, 1);2.3時間戳【減】當(dāng)前午夜時間戳

return currentTime - midnightToday;3.將緩存的日期寫入字符數(shù)組

private void writeDate(final char[] buffer, final int startPos) { if (cachedDate != null) { System.arraycopy(cachedDate, 0, buffer, startPos, dateLength); }}4.將【午夜開始的毫秒數(shù)】轉(zhuǎn)換為時、分、秒… …

計算時分秒及毫秒

小結(jié)

FixedDateFormat在初始化的時候?qū)r區(qū)進(jìn)行了配置,當(dāng)系統(tǒng)默認(rèn)時區(qū)變化的時候,并不會影響到FixedDateFormat中的時區(qū)配置。

Benchmark

在日常開發(fā)中,少不了日期時間格式化,通常的使用方式:

SimpleDateFormat,非線程安全DateTimeFormatter,線程安全log4j中FixedDateFormat、FastDateFormat

不同格式化類的性能測試

一起討論

假設(shè)現(xiàn)在有一套系統(tǒng)部署在東八區(qū),由于業(yè)務(wù)需求,需要在零時區(qū)也部署一套,涉及到時區(qū)方面如何考慮?

國際化

以上就是關(guān)于pos機(jī)時間不對,改變JVM默認(rèn)時區(qū)是否影響log4j打印日志中的日期時間的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機(jī)時間不對的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://www.nxzs9ef.cn/newstwo/97870.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。