문제

TimeStamp를 사용하여 날짜+시간을 저장하려고 생각했지만 2038 년의 제한이 있다는 것을 읽었습니다. 내 질문을 대량으로 요구하는 대신, 초보자 사용자도 쉽게 이해할 수 있도록 작은 부품으로 분해하는 것을 선호했습니다. 그래서 내 질문 :

  1. 2038 년 문제는 정확히 무엇입니까?
  2. 왜 발생하고 발생하면 어떻게됩니까?
  3. 우리는 그것을 어떻게 해결합니까?
  4. 비슷한 문제를 일으키지 않는 사용에 대한 가능한 대안이 있습니까?
  5. 실제로 발생하는 문제를 피하기 위해 타임 스탬프를 사용하는 기존 응용 프로그램에 무엇을 할 수 있습니까?

미리 감사드립니다.

도움이 되었습니까?

해결책

나는 이것을 커뮤니티 위키로 표시 했으므로 여가에서 자유롭게 편집하십시오.

2038 년 문제는 정확히 무엇입니까?

"2038 년 문제 (유닉스 밀레니엄 버그라고도 함, Y2K 문제와 유사하게 Y2K38) 일부 컴퓨터 소프트웨어가 2038 년 전 또는 해에 실패 할 수 있습니다.이 문제는 시스템 시간을 서명 한 32로 저장하는 모든 소프트웨어 및 시스템에 영향을 미칩니다. -정수를 비우고 1970 년 1 월 1 일에 00:00:00 UTC 이후 몇 초로 해석하십시오. "


왜 발생하고 발생하면 어떻게됩니까?

너머의 시간 03:14:07 2038 년 1 월 19 일 화요일 UTC 이 시스템은 1901 년 12 월 13 일에 2038 년이 아닌 시간으로 해석 할 '랩 랩 (whal and the the the the)'이라는 마이너스로 저장 될 것입니다. 이는 UNIX Epoch 이후 몇 초가 있다는 사실 때문입니다 (1 월 1 일. 1970 00:00:00 GMT)는 32 비트 서명 정수에 대한 컴퓨터의 최대 값을 초과했습니다.


우리는 그것을 어떻게 해결합니까?

  • 긴 데이터 유형 사용 (64 비트가 충분합니다)
  • MySQL (또는 mariadb)의 경우 시간 정보가 필요하지 않은 경우 사용을 고려하십시오. DATE 열 유형. 더 높은 정확도가 필요한 경우 사용하십시오 DATETIME 보다는 TIMESTAMP. 조심하십시오 DATETIME 열은 시간대에 대한 정보를 저장하지 않으므로 응용 프로그램은 어떤 시간대를 사용했는지 알아야합니다.
  • Wikipedia에 설명 된 다른 가능한 솔루션
  • MySQL Devs가 수정 될 때까지 기다리십시오 이 버그 10 년 전에보고했습니다.

비슷한 문제를 일으키지 않는 사용에 대한 가능한 대안이 있습니까?

데이터베이스에 날짜를 저장하기 위해 대형 유형을 사용할 수있는 곳을 시도해보십시오. 64 비트는 충분합니다 - GNU C 및 POSIX/SUS의 긴 긴 유형입니다. sprintf('%u'...) PHP 또는 BCMATH 확장에서.


우리가 아직 2038 년에 있지 않더라도 잠재적으로 잠재적으로 사용되는 유스 케이스는 무엇입니까?

그래서 MySQL 날짜 시간 범위는 1000-9999이지만 타임 스탬프의 범위는 1970-2038입니다. 시스템이 생년월일을 저장하거나 미래의 전진 날짜 (예 : 30 년 모기지) 또는 이와 유사한 경우 이미이 버그가 발생할 것입니다. 다시 말하지만, 이것이 문제가 될 경우 타임 스탬프를 사용하지 마십시오.


실제로 발생하는 문제를 피하기 위해 타임 스탬프를 사용하는 기존 응용 프로그램에 무엇을 할 수 있습니까?

Web은 아직 레거시 플랫폼이 아니기 때문에 PHP 응용 프로그램이 여전히 2038 년에 남아있을 것입니다.

다음은 변환 할 데이터베이스 테이블 열을 변경하는 프로세스입니다. TIMESTAMP 에게 DATETIME. 임시 열을 만드는 것으로 시작합니다.

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

자원

다른 팁

UNIX 타임 스탬프를 사용하여 날짜를 저장하는 경우 실제로는 32 비트 정수를 사용하여 1970-01-01 이후 몇 초를 유지합니다. 보다 유닉스 시간

32 비트 수는 2038 년에 넘쳐납니다. 이것이 2038 문제입니다.


이 문제를 해결하려면 날짜를 저장하기 위해 32 비트 UNIX 타임 스탬프를 사용해서는 안됩니다. 즉, MySQL을 사용할 때는 사용하지 않아야합니다. TIMESTAMP, 하지만 DATETIME (보다 10.3.1. DateTime, 날짜 및 타임 스탬프 유형) :

그만큼 DATETIME 날짜와 시간 정보가 모두 포함 된 값이 필요할 때 유형이 사용됩니다. 지원되는 범위는입니다 '1000-01-01 00:00:00' 에게 '9999-12-31 23:59:59'.

그만큼 TIMESTAMP 데이터 유형은 범위가 있습니다 '1970-01-01 00:00:01' UTC '2038-01-19 03:14:07' UTC.


그만큼 (아마) 해당 문제를 피하거나 수정하기 위해 응용 프로그램에 할 수있는 가장 좋은 방법은 사용하지 않는 것입니다. TIMESTAMP, 하지만 DATETIME 1970 년에서 2038 년 사이가 아닌 날짜를 포함 해야하는 열의 경우.

그래도 하나의 작은 메모 : 아마도 매우 높을 것입니다. (통계적으로 말하면) 2038 년 전에 신청서가 꽤 많이 다시 작성되었을 것입니다. 귀하의 신청서의 ...

Google의 빠른 검색은 다음을 수행합니다. 2038 년 문제

  1. 2038 년 문제 (Y2K 문제와 유사하게 Unix Millennium Bug, Y2K38이라고도 함)는 일부 컴퓨터 소프트웨어가 2038 년 전 또는 해에 실패 할 수 있습니다.
  2. 이 문제는 시스템 시간을 서명 된 32 비트 정수로 저장하는 모든 소프트웨어 및 시스템에 영향을 미치고이 숫자가 1970 년 1 월 1 일 00:00:00 UTC 이후 몇 초로 해석합니다.이 방법으로 표현할 수있는 최신 시간. 2038 년 1 월 19 일 화요일에 UTC는 03:14:07 UTC입니다.이 순간을 넘어서는 시간을 넘어서서 내부적으로 마이너스 숫자로 저장 될 것입니다.
  3. 기존 CPU/OS 조합, 기존 파일 시스템 또는 기존 바이너리 데이터 형식에 대한이 문제에 대한 쉬운 수정은 없습니다.

http://en.wikipedia.org/wiki/year_2038_problem 대부분의 세부 사항이 있습니다

요약해서 말하자면:

1) + 2) 문제는 많은 시스템이 1970 년 1 월 1 일 이후 초 수와 동일한 32 비트 로그인 된 int로 날짜 정보를 저장한다는 것입니다. 이와 같이 저장할 수있는 최신 날짜는 2038 년 1 월 19 일 화요일에 03:14:07 UTC입니다. 이런 일이 발생하면 int는 "포장"되어 1901 년에 날짜로 해석 될 음수로 저장됩니다. 정확히 일어날 일은 시스템마다 다르지만 아마도 그것들 중 어느 누구에게도 좋지 않을 것이라고 말하면 충분합니다!

과거의 날짜 만 저장하는 시스템의 경우 한동안 걱정할 필요가 없다고 생각합니다! 주요 문제는 향후 날짜와 함께 작동하는 시스템에 관한 것입니다. 시스템이 앞으로 28 년 동안 날짜로 작업해야한다면 지금 걱정하기 시작해야합니다!

3) 사용 가능한 대체 날짜 형식 중 하나를 사용하거나 64 비트 시스템으로 이동하여 64 비트 INT를 사용하십시오. 또는 데이터베이스의 경우 대체 타임 스탬프 형식을 사용합니다 (예 : MySQL 사용 DateTime의 경우)

4) 3 참조!

5) 4 참조 !!! ;)

BROS, 타임 스탬프를 표시하기 위해 PHP를 사용해야하는 경우 UNIX_TIMESTAMP 형식에서 변경하지 않고 최고의 PHP 솔루션입니다.

custom_date () 함수를 사용하십시오. 그 안에는 dateTime을 사용하십시오. 다음은 DateTime 솔루션입니다.

데이터베이스의 타임 스탬프로 서명되지 않은 Bigint (8)가있는 한. PHP 5.2.0 ++가있는 한

업그레이드하고 싶지 않기 때문에 백엔드 (MSSQL)에게 PHP 대신이 작업을 수행하도록 요청했습니다!

$qry = "select DATEADD(month, 1, :date) next_date ";
$rs_tmp = $pdo->prepare($qry);
$rs_tmp->bindValue(":date", '2038/01/15');
$rs_tmp->execute();
$row_tmp = $rs_tmp->fetch(PDO::FETCH_ASSOC);

echo $row_tmp['next_date'];

효율적인 방법은 아니지만 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top