PHP 및 mySQL : 2038 년 버그 : 무엇입니까? 그것을 해결하는 방법?
TIMESTAMP를 사용하여 날짜 + 시간을 저장하려고 생각했지만 2038 년 제한이 있다는 것을 읽었습니다. 대량으로 질문하는 대신 초보 사용자도 쉽게 이해할 수 있도록 작은 부분으로 나누는 것을 선호했습니다. 그래서 내 질문 (들) :
- 2038 년 문제는 정확히 무엇입니까?
- 왜 발생하고 발생하면 어떻게됩니까?
- 어떻게 해결합니까?
- 비슷한 문제를 일으키지 않는 사용에 대한 가능한 대안이 있습니까?
- TIMESTAMP를 사용하는 기존 애플리케이션에 대해 소위 문제가 실제로 발생하는 것을 방지하기 위해 무엇을 할 수 있습니까?
미리 감사드립니다.
나는 이것을 커뮤니티 위키로 표시 했으므로 편하게 편집 할 수 있습니다.
2038 년 문제는 정확히 무엇입니까?
"2038 년 문제 (Y2K 문제와 유사하게 Unix Millennium Bug, Y2K38라고도 함)로 인해 일부 컴퓨터 소프트웨어가 2038 년 이전 또는 2038 년에 실패 할 수 있습니다.이 문제는 시스템 시간을 서명 된 32로 저장하는 모든 소프트웨어 및 시스템에 영향을줍니다. -비트 정수이고이 숫자를 1970 년 1 월 1 일 00:00:00 UTC 이후의 초 수로 해석합니다. "
왜 발생하고 발생하면 어떻게됩니까?
2038 년 1 월 19 일 화요일 03:14:07 UTC 이후의 시간 은 ' 순환 '되어 내부적으로 음수로 저장되며,이 시스템은 2038 년이 아닌 1901 년 12 월 13 일의 시간으로 해석됩니다. UNIX 시대 (1970 년 1 월 1 일 00:00:00 GMT) 이후의 시간 (초)이 32 비트 부호있는 정수에 대한 컴퓨터의 최대 값을 초과했다는 사실.
어떻게 해결합니까?
- 긴 데이터 유형 사용 (64 비트이면 충분 함)
- MySQL (또는 MariaDB)의 경우 시간 정보가 필요하지 않으면
DATE
열 유형을 사용하는 것이 좋습니다. 더 높은 정확도가 필요한DATETIME
경우TIMESTAMP
. 조심하십시오DATETIME
응용 프로그램이 사용 된 시간대 알고 있어야합니다, 그래서 열이 시간대에 대한 정보를 저장하지 않습니다. - Wikipedia에 설명 된 다른 가능한 솔루션
- MySQL 개발자가 10 년 전에보고 된 이 버그 를 수정할 때까지 기다리십시오 .
비슷한 문제를 일으키지 않는 사용에 대한 가능한 대안이 있습니까?
데이터베이스에 날짜를 저장하기 위해 가능한 한 큰 유형을 사용하도록 시도하십시오. 64 비트이면 충분합니다. GNU C 및 POSIX / SuS 또는 sprintf('%u'...)
PHP 또는 BCmath 확장 의 long long 유형입니다 .
아직 2038 년이 아니지만 잠재적으로 파괴되는 사용 사례에는 어떤 것이 있습니까?
따라서 MySQL DATETIME 의 범위는 1000-9999이지만 TIMESTAMP의 범위는 1970-2038입니다. 시스템에 생년월일, 미래의 미래 날짜 (예 : 30 년 모기지) 또는 이와 유사한 정보가 저장되어 있으면 이미이 버그가 발생하게됩니다. 다시 말하지만 이것이 문제가 될 경우 TIMESTAMP를 사용하지 마십시오.
TIMESTAMP를 사용하는 기존 애플리케이션에 대해 소위 문제가 실제로 발생하는 것을 방지하기 위해 무엇을 할 수 있습니까?
웹이 아직 레거시 플랫폼이 아니기 때문에 예측하기는 어렵지만 2038 년에는 PHP 애플리케이션이 거의 없을 것입니다.
다음은 변환 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 타임 스탬프를 사용하여 날짜를 저장할 때 실제로는 1970-01-01 이후의 초 수를 유지하는 32 비트 정수를 사용합니다. Unix 시간 참조
그 32 비트 숫자는 2038 년에 넘칠 것입니다. 이것이 2038 년 문제입니다.
이 문제를 해결하기 위해, 당신은 당신의 날짜 저장하는 데 32 개 비트를 UNIX 타임 스탬프를 사용해서는 안 - 수단, MySQL을 사용하는 경우, 당신은 사용하지 말아야 TIMESTAMP
하지만 DATETIME
(참조 10.3.1을 DATETIME, DATE, 및 TIMESTAMP 유형. )
이
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합니다.
The (probably) best thing you can do to your application to avoid/fix that problem is to not use TIMESTAMP
, but DATETIME
for the columns that have to contain dates that are not between 1970 and 2038.
One small note, though : there is a very high probably (statistically speaking) that your application will have been re-written quite a couple of times before 2038 ^^ So maybe, if you don't have to deal with dates in the future, you won't have to take care of that problem with the current version of your application...
A quick search on Google will do the trick: Year 2038 problem
- The year 2038 problem (also known as Unix Millennium Bug, Y2K38 by analogy to the Y2K problem) may cause some computer software to fail before or in the year 2038
- The problem affects all software and systems that store system time as a signed 32-bit integer, and interpret this number as the number of seconds since 00:00:00 UTC on January 1, 1970. The latest time that can be represented this way is 03:14:07 UTC on Tuesday, 19 January 2038. Times beyond this moment will "wrap around" and be stored internally as a negative number, which these systems will interpret as a date in 1901 rather than 2038
- There is no easy fix for this problem for existing CPU/OS combinations, existing file systems, or existing binary data formats
http://en.wikipedia.org/wiki/Year_2038_problem has most of the details
In summary:
1) + 2) The problem is that many systems store date info as a 32-bit signed int equal to the number of seconds since 1/1/1970. The latest date that can be stored like this is 03:14:07 UTC on Tuesday, 19 January 2038. When this happens the int will "wrap around" and be stored as a negative number which will be interpreted as a date in 1901. What exactly will happen then, varies from system to system but suffice to say it probably won't be good for any of them!
For systems that only store dates in the past, then I guess you don't need to worry for a while! The main problem is with systems that work with dates in the future. If your system needs to work with dates 28 years in the future then you should start worrying now!
3) Use one of the alternative date formats available or move to a 64-bit system and use 64-bit ints. Or for databases use an alternative time stamp format (eg for MySQL use DATETIME)
4) See 3!
5) See 4!!! ;)
Bros, if you need to use PHP to display timestamps, this is the BEST PHP solution without changing from UNIX_TIMESTAMP format.
Use a custom_date() function. Inside it, use the DateTime. Here's the DateTime solution.
As long as you have UNSIGNED BIGINT(8) as your timestamps in database. As long as you have PHP 5.2.0 ++
As I did't want to upgrade anything, I asked my backend (MSSQL) to do this job instead of 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'];
May not be an efficient way, but it works.
참고URL : https://stackoverflow.com/questions/2012589/php-mysql-year-2038-bug-what-is-it-how-to-solve-it
'Programming' 카테고리의 다른 글
enum의 생성자가 정적 필드에 액세스 할 수없는 이유는 무엇입니까? (0) | 2020.08.23 |
---|---|
Math.Floor (Double)가 Double 유형의 값을 반환하는 이유는 무엇입니까? (0) | 2020.08.23 |
프로그래밍 방식으로 기기의 Android API 수준을 얻습니까? (0) | 2020.08.23 |
예외가 발생할 때까지 GDB에서 응용 프로그램 실행 (0) | 2020.08.23 |
yield ()의 주요 용도는 무엇이며 join () 및 interrupt ()와 어떻게 다릅니 까? (0) | 2020.08.23 |