pos機時(shí)間不對

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

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

本文目錄一覽:

1、pos機時(shí)間不對

pos機時(shí)間不對

引言

在【JVM & MySQL時(shí)區配置問(wèn)題-兩行代碼讓我們一幫子人熬了一個(gè)通宵】描述了由于代碼BUG導致存儲到數據庫的時(shí)間比正常時(shí)間少八小時(shí)的案例。當時(shí)分析的時(shí)候發(fā)現log4j打印的日志文件中日期時(shí)間都是正確的,下面對這個(gè)問(wèn)題進(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默認時(shí)區:東八區 LOGGER.info("Hello World!"); // 模擬應用問(wèn)題場(chǎng)景:改變JVM默認時(shí)區 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>分析過(guò)程FixedDateFormat

一路跟蹤代碼,最終格式化日期時(shí)間的類(lèi)是: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(); // 默認時(shí)區為東八區 FixedDateFormat fixedDateFormat = FixedDateFormat.createIfSupported(null); String str = fixedDateFormat.format(time); System.out.println(str); // 改變默認時(shí)區為零時(shí)區 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); fixedDateFormat = FixedDateFormat.createIfSupported(null); str = fixedDateFormat.format(time); System.out.println(str); }}初始化

創(chuàng )建FixedDateFormat實(shí)例

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

FixedFormat

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

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

字段

字段示例

說(shuō)明

pattern

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

日期時(shí)間格式

datePattern

yyyy-MM-dd’T’

日期格式

escapeCount

2

pattern中T兩邊單引號的個(gè)數

timeSeparator

:

小時(shí)與分鐘、分鐘與秒之間的分隔符

timeSepLength

1

timeSeparator字符長(cháng)度

millisSeparator

,

秒與毫秒之間的分隔符

millisSepLength

1

millisSeparator字符長(cháng)度

secondFractionDigits

3

millisSeparator后面時(shí)間字符的長(cháng)度

timeZoneFormat

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

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

format

格式化日期流程

1.初始化char數組

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

char數組用于存放格式化后的pattern數據。

2.計算從當天午夜開(kāi)始的毫秒數

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

2.2.1格式化日期并緩存

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

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計算當前午夜時(shí)間戳

midnightToday = calcMidnightMillis(now, 0);

計算午夜時(shí)間戳

2.2.3計算明天午夜時(shí)間戳

與2.2.2不同的是addDays是1。

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

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

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

計算時(shí)分秒及毫秒

小結

FixedDateFormat在初始化的時(shí)候對時(shí)區進(jìn)行了配置,當系統默認時(shí)區變化的時(shí)候,并不會(huì )影響到FixedDateFormat中的時(shí)區配置。

Benchmark

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

SimpleDateFormat,非線(xiàn)程安全DateTimeFormatter,線(xiàn)程安全log4j中FixedDateFormat、FastDateFormat

不同格式化類(lèi)的性能測試

一起討論

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

國際化

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

轉發(fā)請帶上網(wǎng)址:http://m.xjcwpx.cn/newstwo/97870.html

你可能會(huì )喜歡:

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