sourcetip

웹 응용프로그램에서 시간대 처리

fileupload 2023. 9. 25. 22:55
반응형

웹 응용프로그램에서 시간대 처리

웹 애플리케이션에서 우리는 서로 다른 시간대의 국가별 날짜 시간 정보를 표시하고 입력해야 합니다.현재 국가별로 별도의 웹 서버와 별도의 데이터베이스(오라클 11g)를 유지하고 있습니다.

단일 데이터베이스(oracle 11g)로 하나의 포털에 모두 병합할 예정입니다.이 포털은 사용자 현지 시간대에 날짜와 시간을 캡처/표시해야 합니다.

지금까지 이것에 대해 검색해보았는데, 아래의 제안을 받았습니다.

1) 웹 서버 및 데이터베이스 서버의 시간대를 UTC로 설정하고 데이터(데이터 및 시간)를 가져오는 동안 사용자 로컬 시간대로 변환합니다.

이 방법을 제안하는 경우 다음과 같은 구체적인 질문을 명확히 해 주시기 바랍니다.

  • 날짜만 캡처하는 경우가 대부분인데 항상 시간대와 함께 날짜와 시간을 캡처해야 합니까?

  • 사용자 현지 시간대를 UTC로 변환해야 하는 날짜와 시간을 javascript/java/oracle로 저장하는 동안?

  • UTC를 사용자로 변환해야 하는 날짜와 시간을 가져오는 동안
    로컬 시간대 쿼리 자체/java/java 스크립트?

  • 와 같은 으로 보여줄 가 많은 입니다.
    오늘/현재월/날짜 범위입니다. 할 수 - - 이를 어떻게 처리할 수 있습니까(입력 - 사용자 현지 시간대 - UTC의 데이터베이스)?

  • 날짜 필드(날짜/timestamp/시간대가 있는 timestamp/시간대가 있는 timestamp)에 사용해야 하는 데이터 유형은 무엇입니까?

2) 사용자 현지 시간대와 UTC 모두에서 날짜와 시간을 캡처합니다.별도의 열로 저장되며, 사용자 로컬 시간대는 디스플레이 목적으로 사용되며 UTC는 비즈니스 로직으로 사용됩니다.

이 방법을 제안하는 경우 다음과 같은 구체적인 질문을 명확히 해 주시기 바랍니다.

  • 사용자 현지 시간대와 UTC를 저장하는 것이 일반적인 관례입니까?

  • 오늘/현재 월/날짜 범위와 같은 날짜 열을 기준으로 표시할 보고서를 가져오는 동안 상태를 확인해야 하는 열은 무엇입니까?


  • p의와의 타임스탬프계 타임스탬프p)
    존)?

미리 감사드립니다

질문 일광 절약 시간 시간대 모범 사례를 읽어 보십시오.당신 것은 기본적으로 복제품입니다.

UTC의 서버

예, 일반적으로 서버는 해당 OS를 UTC로 시간대로 설정하거나 제공되지 않는 경우 사용합니다.GMT레이캬비크 아이슬란드 시간대를 선택할 수도 있습니다.Java 구현에서는 이 설정을 현재 기본 시간대로 선택할 수 있습니다.

표준 시간대 지정

그러나 UTC로 설정된 시간대에 의존하지 마십시오.시스템 관리자가 변경할 수 있습니다.또한 JVM 내의 모든 앱의 스레드에 있는 Java 코드는 실행 에 호출을 통해 JVM의 현재 기본 시간대를 변경할 수 있습니다.따라서 대신 Java 코드의 선택적 인수를 통과하여 원하는/예상 시간대를 항상 지정하는 습관을 들여야 합니다.

저는 날짜-시간 프레임워크가 시간대를 선택적으로 만들 수 있는 설계상의 결함이라고 생각합니다.선택 사항이 되는 것은 다른 모든 사람들처럼 프로그래머들이 자극을 받지 않는 한 무의식적으로 자신의 개인 시간대에 대해 생각하기 때문에 끝없는 혼란을 야기합니다.그래서 데이트 시간에 너무 자주 하는 일들은 그 문제에 주의를 기울이지 않습니다.JVM 기본값이 달라진다는 문제를 추가합니다.그런데, 같은 문제에 대해서는 ditto를 항상 명시적으로 지정해야 합니다.

UTC

비즈니스 로직, 데이터 스토리지 및 데이터 교환은 거의 항상 UTC에서 수행되어야 합니다.거의 모든 데이터베이스에 UTC에 입력을 조정하고 UTC에 저장할 수 있는 기능이 있습니다.

사용자에게 날짜-시간을 제시할 때 예상 시간대로 조정합니다.날짜-시간 값을 직렬화할 때 ISO 8601 문자열 형식을 사용합니다.구체적으로는 Oracle에 대한 Vicky Arora의 답변을 참조하십시오(나는 Postgres 사람입니다).문서를 주의 깊게 읽고 데이터베이스의 동작을 완전히 이해하기 위해 실험을 통해 연습해야 합니다.이와 관련하여 SQL 사양의 철자가 그리 많지 않으며 동작도 매우 다양합니다.

java.sql

Java 및 JDBC를 사용할 경우 및 관련 데이터 유형을 사용하게 됩니다.그들은 항상 자동적으로 UTC에 있습니다.앞으로 자바 8 이상에 내장된 java.time 프레임워크에 정의된 새로운 데이터 유형을 직접 사용하도록 JDBC 드라이버가 업데이트될 것으로 예상됩니다.

java.time

오래된 클래스는 java.time에 의해 구식입니다.기존의 java.util을 피하면서 java.time을 사용하는 방법을 배웁니다.날짜/.스케줄을 조정하고 프로그래밍 생활을 훨씬 더 즐겁게 만들어 줍니다.

JDBC 드라이버가 업데이트될 때까지 java.time에 내장된 변환 편의 방법을 사용할 수 있습니다.다음 예제를 참조하십시오. 여기서 는 UTC의 순간이고 시간대로 조정된 순간입니다.

Instant instant = myJavaSqlTimestamp.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

반대 방향으로.

java.sql.Timestamp myJavaSqlTimestamp = java.sql.Timestamp.from( zdt.toInstant() );

원시간대가 필요하시면 보관해주세요.

비즈니스 요구 사항에서 원래 입력 데이터의 시간대를 중요하게 생각하거나 기억해야 하는 경우 데이터베이스 테이블에 별도의 열로 명시적으로 저장합니다.오프셋-from-UTC를 사용할 수 있지만, 이는 전체 정보를 제공하지는 않습니다.시간대는 오프셋과 일광 절약 시간과 같은 이상 징후의 과거, 현재 및 미래 처리에 대한 규칙 집합입니다.따라서 적절한 시간대 이름은 다음과 같이 가장 적절합니다.America/Montreal.

날짜만 애매합니다.

시간대와 시간대가 없는 날짜 전용 값을 많이 수집한다고 했습니다.는 java.time 입니다.LocalDate. 및 에서와 마찬가지로 "로컬…" 부분은 특정 지역성을 의미하지 않으므로 시간대의 한 점이 아닌 시간대는 실제 의미가 없습니다.

날짜 전용 값은 정의에 따라 모호합니다.어느 순간이든 날짜는 전 세계적으로 다릅니다.예를 들어, 파리에서는 자정이 조금 지난 후에 프랑스는 새로운 날이지만, 몬트리올 퀘백에서는 날짜가 여전히 "어제"입니다.

보통 비즈니스에서 어떤 시간대는 암묵적이고, 심지어 무의식적으로 직감하기도 합니다.데이터 포인트에 대한 무의식적인 직관은 장기적으로, 특히 소프트웨어에서는 잘 작동하지 않는 경향이 있습니다.어떤 시간대를 의도했는지 명시하는 것이 좋습니다.데이터베이스 테이블에 다른 열과 같은 날짜와 함께 원하는 영역을 저장하거나 프로그래밍 코드에 주석을 달 수 있습니다.날짜 값을 저장하는 것이 훨씬 더 좋고 안전할 것이라고 생각합니다.그렇다면 어떻게 날짜 전용을 날짜-시간으로 변환할 수 있을까요?

종종 새로운 날은 하루의 첫번째 순간인 자정 이후의 순간입니다.당신은 그것이 하루의 시간을 의미한다고 생각할지도 모릅니다.00:00:00.0그러나 항상은 아닙니다.일광 절약 시간(DST) 및 기타 이상 징후로 인해 첫 번째 순간이 다른 벽시계 시간으로 이동할 수 있습니다.java.time이 첫번째 순간에 정확한 시간을 결정하도록 합니다.LocalDate수업 및 그 방법

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
ZonedDateTime todayStart = today.atStartOfDay( zoneId );

어떤 업무 환경에서는 새로운 날을 업무 시간으로 정의(또는 가정)할 수도 있습니다.예를 들어, 뉴욕의 한 출판사가 현지 시간으로 오전 9시를 의미한다고 하자, 그들은 "도서 초안이 1월 2일까지 제출되어야 한다"고 말합니다.그 날짜의 시간대를 그 시간대로 잡읍시다.

ZoneId zoneId = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = ZonedDateTime.of( 2016 , 1 , 2 , 9 , 0 , 0 , 0 , zoneId );

뉴질랜드에서 일하는 작가에게 그것은 어떤 의미일까요?전화를 걸어 그녀에게 설명하기 위해 그녀의 특정 시간대에 맞추세요.

ZoneId zoneId_Pacific_Auckland = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt_Pacific_Auckland = zdt.withZoneSameInstant( zoneId_Pacific_Auckland );

데이터베이스

데이터베이스 스토리지의 경우 위에서 본 것처럼 (UTC 타임라인의 한 순간)으로 변환하여 전달합니다.

java.sql.Timestamp ts = java.sql.Timestamp.from( zdt.toInstant() );

데이터베이스에서 검색되면 뉴욕 날짜-시간으로 변환합니다.에서의 변환java.sql.Timestamp완전히Instant, 그런 다음 시간대를 적용합니다.ZoneId를을 ZonedDateTime.

Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

데이터베이스 드라이버JDBC 4.2 이상을 준수하는 경우 java.sql 유형으로 변환하거나 변환하지 않고 java.time 유형을 직접 전달/가져올 수 있습니다.와 방법을 시도해 봅니다.


데이터베이스가 데이터베이스와 세션 표준 시간대 사이의 시간을 자동으로 변환하도록 하려면.

소수점 정밀도가 최대 9개인 날짜 및 시간을 저장합니다.이 데이터 유형은 시간대 차이에 민감합니다.이 유형의 값은 데이터베이스 표준 시간대와 로컬(세션) 표준 시간대 사이에서 자동으로 변환됩니다.값이 데이터베이스에 저장되면 데이터베이스 표준 시간대로 변환되지만 로컬(세션) 표준 시간대는 저장되지 않습니다.데이터베이스에서 값을 검색하면 해당 값이 데이터베이스 표준 시간대에서 로컬(세션) 표준 시간대로 변환됩니다.

여기서 저는 다음과 같은 구체적인 질문을 명확히 했습니다.

Q. 날짜만 캡처하는 경우가 대부분인데, 항상 시간대와 함께 날짜와 시간을 캡처해야 합니까?

A.

Q. 사용자 현지 시간대를 UTC로 변환해야 하는 날짜와 시간을 javascript/java/oracle에 저장하고 있습니까?

A. 데이터 저장 중 변환 불가, 원본 날짜+시간+구역 그대로 저장

Q. UTC를 사용자 로컬 시간대로 변환해야 하는 날짜와 시간을 가져오는 동안 쿼리 자체/자바/자바 스크립트?

A. 애플리케이션이 열린 현지 시간대 또는 UTC 형식으로 항상 표시되도록 변환합니다.

Q. 오늘/현재 월/날짜 범위와 같이 날짜 열을 기준으로 표시할 보고서가 많은 곳입니다.이를 어떻게 처리할 수 있습니까(입력 - 사용자 현지 시간대 - UTC의 데이터베이스)?

A. 시스템은 애플리케이션이 열린 로컬 또는 UTC 중 어떤 형식으로 날짜 시간 표시를 위한 설정 옵션을 사용자에게 제공해야 합니다.모든 작업은 프론트 엔드에서만 수행됩니다.

Q. 날짜 필드에 사용해야 하는 데이터 유형(날짜/타임스탬프/타임스탬프/타임스탬프/타임스탬프/타임스탬프/지역 시간대)은 무엇입니까?

A. 타임스탬프

즉, 날짜 시간을 소스 시간대에 저장하고 페이지가 열린 로컬 또는 UTC 형식의 사용자 선호에 따라 변환합니다.변환은 표시용 스크립트를 통해서만 수행됩니다.제품이 인기를 끌고 있는 지역도 찾아볼 수 있습니다.

DB에 저장되어 있는 기존의 날짜를 간단히 다음과 같이 변경합니다.Long, 그리고 지속성(ETL 프로세스) 이것.Long알려진 값(또는 차감된 값)과 함께pattern,Locale그리고.TimeZone(기본 메타).그리고 새로운 것을 지속합니다.Date기본 메타와 함께라면 가능합니다.

ETL 예제

예를 들자면2015-11-29 10:07:49.500 UTC가 DB에 저장됩니다.

// Known or deducted format of the persisted date
String   pattern = "yyyy-MM-dd HH:mm:ss.SSS"; 
Locale   locale  = Locale.ENGLISH;
TimeZone zone    = "UTC";

// Date to ms
SimpleDateFormat sdf = new SimpleDateFormat(pattern, locale);
sdf.setTimeZone(TimeZone.getTimeZone(zone));
Date date = sdf.parse(pattern);

// ETL: Can now be persisted in Long, along with default META (pattern, Locale, TZ)
Long dateL = date.getTime(); // for e.g. 1448827660720
...

고집불통.Long필요한 경우 값을 다른 형식으로 변환할 수도 있습니다.

pattern                  | locale   | tz   |  result
============================================
yyyy/MM/dd               | null     | null |  2015/11/29          
dd-M-yyyy hh:mm:ss       | null     | null |  29-11-2015 10:07:40
dd MMMM yyyy zzzz        | ENGLISH  | null |  29 November 2015 Central European Time
yyyy-MM-dd HH:mm:ss.SSS  | null     | UTC  |  2015-11-29 10:07:49 UTC

실현 가능하고 논리적인 접근 방식은 사용자가 입력한 시간을 GMT/UTC +00으로 변환하고 시간대 식별자가 있든 없든 상관없는 것을 db에 저장합니다.사용자가 java의 GMT/UTC 시간을 사용자의 로컬 시간으로 변환하는 시간을 표시해야 할 경우

당신은 Joda Time을 고려하고 첫번째 제안을 따라야 합니다.JodaTime에는 LocalDate, LocalDateTime과 같은 다양한 클래스가 있습니다. 이 클래스는 다양한 사용 사례에 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/33343893/handling-time-zone-in-web-application

반응형