Domanda

Stavo pensando di utilizzare TIMESTAMP per memorizzare la data + tempo, ma ho letto che c'è un limite di 2038 su di esso. Invece di chiedere la mia domanda alla rinfusa, ho preferito suddividerlo in piccoli pezzi in modo che sia facile per gli utenti meno esperti a capire come bene. Quindi la mia domanda (s):

  1. Che cosa è esattamente il problema dell'anno 2038?
  2. Perché si verifichi e che cosa succede quando si verifica?
  3. Come possiamo risolverlo?
  4. Ci sono le possibili alternative all'utilizzo di esso, che non pongono un problema simile?
  5. Che cosa possiamo fare per le applicazioni esistenti che utilizzano TIMESTAMP, per evitare il cosiddetto problema, quando si verifica davvero?

Grazie in anticipo.

È stato utile?

Soluzione

ho segnato questo come un wiki comunità quindi sentitevi liberi di modificare a vostro piacimento.

che cosa è esattamente il problema dell'anno 2038?

"Il problema dell'anno 2038 (noto anche come Unix Millennium Bug, Y2K38 per analogia al problema Y2K) può causare qualche software per computer a fallire prima o nel corso dell'anno 2038. Il problema riguarda tutti i software e sistemi che memorizzano ora di sistema come un segno a 32 bit integer, e interpretare questo numero come il numero di secondi dal 00:00:00 UTC del 1 gennaio, 1970 ".


Perché si verifichi e che cosa succede quando si verifica?

Tempi di là di 03:14:07 UTC Martedì 19 gennaio 2038 'avvolgente' e essere memorizzati internamente come un numero negativo, che questi sistemi interpreteranno come un tempo in December 13, 1901 piuttosto che nel 2038. Ciò è dovuto al fatto che il numero di secondi dalla Unix Epoch (1 Gennaio 1970 00:00:00 GMT) avrà superato il valore massimo di un computer per un intero con segno a 32 bit.


Come possiamo risolverlo?

  • Utilizzare i tipi di dati lungo (64 bit sono sufficienti)
  • Per MySQL (o MariaDB), se non è necessario le informazioni di tempo è consigliabile utilizzare il tipo di colonna DATE. Se avete bisogno di una maggiore precisione, utilizzare DATETIME piuttosto che TIMESTAMP. Attenzione che DATETIME colonne non memorizzano le informazioni sul fuso orario, quindi l'applicazione dovrà sapere quale fuso orario è stato utilizzato.
  • altre possibili soluzioni descritto su Wikipedia
  • Attendere sviluppatori di MySQL per risolvere questo bug ha riportato più di un decennio fa.

Ci sono le possibili alternative all'utilizzo di esso, che non pongono un problema simile?

Prova ove possibile usare grandi tipi per memorizzare date in database:. 64-bit è sufficiente - una lunga tipo lungo in GNU C e POSIX / SuS, o sprintf('%u'...) in PHP o l'estensione bcmath


Quali sono alcuni casi di utilizzo potenzialmente rottura, anche se non siamo ancora nel 2038?

Quindi un MySQL DATETIME ha una gamma di 1000- 9999, ma TIMESTAMP ha solo una gamma di 1970-2038. Se il sistema memorizza date di nascita, le future date a termine (ad esempio 30 anno mutui), o simili, si sta già andando a correre in questo bug. Anche in questo caso, non utilizzare TIMESTAMP se questo sta per essere un problema.


Cosa possiamo fare per le applicazioni esistenti che utilizzano TIMESTAMP, per evitare il cosiddetto problema, quando si verifica davvero?

applicazioni PHP Pochi saranno ancora in giro nel 2038, anche se è difficile prevedere come il web difficilmente una piattaforma legacy ancora.

Qui è un processo per alterare una colonna della tabella di database per convertire TIMESTAMP a DATETIME. Si inizia con la creazione di una colonna temporanea:

# 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`

Risorse

Altri suggerimenti

Quando si utilizza UNIX timestamp per memorizzare le date, in realtà si sta utilizzando un 32 bit interi, che mantiene il conteggio del numero di secondi dal 1970-01-01; vedi Unix Tempo

Questo numero a 32 bit sarà in overflow nel 2038. Questo è il problema 2038.


Per risolvere questo problema, non si deve utilizzare un 32 bit timestamp UNIX per memorizzare le date - il che significa che, quando si utilizza MySQL, non si dovrebbe usare TIMESTAMP, ma DATETIME (vedi 10.3.1 datetime, la data e tipi TIMESTAMP ):.

  

Il tipo DATETIME viene utilizzata quando si   bisogno di valori che contengono sia data e   informazioni in tempo. L'intervallo supportato   è '1000-01-01 00:00:00' a   '9999-12-31 23:59:59'.

     

Il tipo di dati TIMESTAMP ha una gamma   di '1970-01-01 00:00:01' UTC a   '2038-01-19 03:14:07' UTC.


Il (probabilmente) cosa migliore che potete fare per la vostra applicazione per evitare / risolvere questo problema è di non usare TIMESTAMP, ma DATETIME per le colonne che devono contenere le date che non sono tra il 1970 e il 2038.

Una piccola nota, però: c'è un altissimo probabilmente (statisticamente parlando) che l'applicazione sarà stato riscritto piuttosto un paio di volte prima di 2038 ^^ Quindi, forse, se si don 't hanno a che fare con date, in futuro, non si dovrà prendere cura di questo problema con la versione corrente della vostra applicazione ...

Una rapida ricerca su Google farà il trucco: bug dell'anno 2038

  1. Il problema dell'anno 2038 (noto anche come Unix Millennium Bug, Y2K38 per analogia al problema Y2K) può causare qualche software per computer a fallire prima o durante l'anno 2038
  2. Il problema riguarda tutti i software e sistemi che memorizzano ora di sistema come un intero a 32 bit con segno, e interpretano questo numero come il numero di secondi dal 00:00:00 UTC del 1 ° gennaio 1970. L'ultima volta che può essere rappresentato in questo modo è 03:14:07 UTC il Martedì, 19 gennaio 2038. volte oltre questo momento sarà "wrap around" e essere memorizzati internamente come un numero negativo, che questi sistemi interpreteranno come una data nel 1901 piuttosto che 2038
  3. Non v'è alcuna soluzione semplice per questo problema per i formati di dati binari combinazioni di CPU / OS esistenti, i file system esistenti, o esistente

http://en.wikipedia.org/wiki/Year_2038_problem ha la maggior parte del dettagli

In sintesi:

1) + 2) Il problema è che molti sistemi di data negozio informazioni come un 32 bit firmato int uguale al numero di secondi dal 1/1/1970. L'ultima data che può essere memorizzato come questo è 03:14:07 UTC Martedì 19 gennaio 2038. In questo caso l'int sarà "wrap around" ed essere memorizzato come un numero negativo che sarà interpretato come una data nel 1901. che cosa esattamente accadrà poi, varia da sistema a sistema, ma basti dire che probabilmente non sarà un bene per nessuno di loro!

Per i sistemi che solo le date di memorizzare in passato, allora credo che non c'è bisogno di preoccuparsi per un po '! Il problema principale è con i sistemi che funzionano con date in futuro. Se il sistema ha bisogno di lavorare con date 28 anni in futuro, allora si dovrebbe iniziare a preoccuparsi ora!

3) Utilizzare uno dei formati di data alternative disponibili o passare ad un sistema a 64 bit e utilizzare interi a 64 bit. O per database utilizzano un formato di data e ora alternativa (ad esempio per MySQL utilizzare DATETIME)

4) Vedere 3!

5) Vedi 4 !!! ;)

Bros, se avete bisogno di utilizzare PHP per visualizzare data e ora, questa è la soluzione migliore PHP senza cambiare dal formato UNIX_TIMESTAMP.

Utilizzare una funzione custom_date (). Al suo interno, utilizzare il DateTime. Ecco la soluzione DateTime .

Fino a quando si dispone di UNSIGNED BIGINT (8) come le vostre timestamp nel database. Finché si dispone di PHP 5.2.0 ++

Come ho did't voglio aggiornare qualsiasi cosa, ho chiesto al mio backend (MSSQL) per fare questo lavoro, invece di 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'];

Non può essere un modo efficace, ma funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top