Alrededor del año 2000, Apple escribió un comunicado de prensa que cada Mac desde 1984 evitaría el problema Y2K y podría procesar fechas para los próximos miles de años.
La buena noticia es que desde su introducción en 1984, las computadoras Macintosh han tenido la capacidad de hacer la transición al año 2000. De hecho, Mac OS y la mayoría de las aplicaciones de Mac pueden manejar fechas generadas internamente correctamente hasta el año 29,940.
Esta declaración se hizo cuando Mac OS 9 era el sistema operativo más reciente.
Desde entonces, OS X (ahora llamado macOS) es el sistema operativo dominante, que se deriva de Unix. ¿Significa esto que cualquier versión es vulnerable al problema del año 2038 , un problema comparable al problema Y2K que afecta a los sistemas tipo Unix? ¿O sigue siendo cierta la declaración que dio Apple sobre ser compatible con el año 29,940?
Todas las versiones anteriores a OS X 10.6 "Snow Leopard" tienen el problema del año 2038. La mayoría de las instalaciones de 10.6 y todas las instalaciones de 10.7 "Lion" solucionaron la causa principal del problema. Casi ha desaparecido, pero el error del año 2038 podría sobrevivir en algunas aplicaciones.
Mi antiguo PowerPC Mac ejecuta OS X 10.4.11 "Tiger". Fui a Fecha y hora en Preferencias del sistema e intenté ingresar una fecha posterior a 2038, pero restableció la fecha al 31 de diciembre de 2037. Sabe que algo anda mal en 2038.
OS X se deriva de Unix a través de BSD. Las aplicaciones para OS X usan llamadas del sistema BSD para cosas como abrir archivos y conectarse a Internet. BSD tiene una larga historia y algunas de sus llamadas al sistema provienen de la década de 1980. Una de sus llamadas al sistema es gettimeofday()
, que apareció por primera vez en 4.1cBSD. UC Berkeley lanzó 4.1cBSD en 1982 , más de medio siglo antes de 2038. El tiempo desde gettimeofday()
es un número entero de tipo time_t
. Cuenta segundos, donde cero es la época de Unix de 1970-01-01 00:00:00 UTC.
En mi antiguo PowerPC Mac, time_t
es un entero de 32 bits con signo. Esto causa el problema del año 2038. Un 32 bits firmado time_t
tiene un rango de -2147483648 a 2147483647. Esto solo puede contener tiempos desde 1901-12-13 20:45:52 UTC hasta 2038-01-19 03:14:07 UTC. Cuando esto se desborde, gettimeofday()
cambiará la fecha del lunes 19 de enero de 2038 al viernes 13 de diciembre de 1901.
La solución es hacer la transición de 32 bits time_t
a 64 bits time_t
. Para OS X, esta transición ocurrió junto con otra transición de punteros de 32 bits a punteros de 64 bits, pero los punteros de 64 bits requieren un procesador de 64 bits. Apple solo ha proporcionado 64 bits time_t
para procesadores de 64 bits. Es posible que los procesadores de 32 bits manejen 64 bits time_t
, pero Apple nunca proporcionó esa característica.
Los compiladores de Apple han admitido números enteros de 64 bits en procesadores de 32 bits desde OS X 10.0 "Cheetah", cuando time_t
tenía 32 bits y off_t
tenía 64 bits. En Unix y BSD, off_t
es el tamaño de un archivo o de un disco completo. Una versión de 32 bits off_t
limitaría OS X a discos de menos de 2 GiB. Apple lo definió off_t
como 64 bits, por lo que OS X funcionaba con discos más grandes. Apple definió time_t
como 32 bits en 10.0, por lo que la transición a 64 bits time_t
debía ocurrir más tarde.
Para mi antiguo PowerPC Mac, el archivo de encabezado <ppc/_types.h>
se define __darwin_time_t
como long
. Para Intel Mac, el encabezado <i386/_types.h>
hace lo mismo. En OS X, long
tiene el mismo tamaño que un puntero. Entonces, cuando los punteros se convirtieron en 64 bits, long
también se convirtieron en 64 bits y time_t
también se convirtieron en 64 bits, solucionando la causa principal del problema del año 2038.
La Guía de transición de 64 bits de Apple dice: "Antes de OS X v10.6, todas las aplicaciones que se incluían con el sistema operativo eran aplicaciones de 32 bits. A partir de la versión 10.6, las aplicaciones que se incluían con el sistema operativo eran generalmente aplicaciones de 64 bits". ." Sé por Wikipedia que 10.6 requería un procesador Intel y 10.7 requería un procesador Intel de 64 bits. Una Mac con 10.6 en un procesador Intel de 32 bits debe haber tenido aplicaciones de 32 bits. Concluyo que la mayoría de las Mac que ejecutan 10.6 y todas las Mac que ejecutan 10.7 tienen aplicaciones de 64 bits con punteros de 64 bits y archivos time_t
. Apple lanzó 10.7 en 2011, mucho antes de enero de 2038.
Con 64 bits time_t
, el error del año 2038 casi desapareció, pero podría sobrevivir en algunas aplicaciones. Es posible que las aplicaciones antiguas de 32 bits aún se ejecuten en sistemas más nuevos. Además, las aplicaciones de 64 bits pueden contener errores de codificación o diseños obsoletos, lo que hace que se conviertan de 64 bits time_t
a 32 bits. Este es un problema para todos los sistemas, no solo macOS.
También hay tiempo de Mach. El kernel de OS X mezcla BSD con Mach. La mayoría de las aplicaciones obtienen la hora de BSD usando gettimeofday()
, pero hay una manera de evitar BSD y obtener la hora de Mach. Esto es más difícil: el programa llamaría mach_host_self()
para obtener el puerto host, luego host_get_clock_service()
para obtener el CALENDAR_CLOCK
, y finalmente clock_get_time()
.
En mi vieja Mac con 10.4 "Tiger", <mach/clock_types.h>
declara la hora como unsigned int
(dentro struct mach_timespec
). Este es un entero de 32 bits sin signo, con un rango de 0 a 4294967295, que es desde 1970-01-01 00:00:00 UTC hasta 2106-02-07 06:28:15 UTC. Esto cambiaría el problema del año 2038 por el problema del año 2106. No puede llegar al año 29.940.
Sospecho que host_get_clock_service()
estaba obsoleto desde 10.0 "Cheetah", porque Apple proporcionó formas más rápidas de obtener el tiempo. Estos fueron BSD gettimeofday()
para tiempo de calendario y Apple mach_absolute_time()
para tiempo monótono. La preferencia por gettimeofday()
poner el problema en 2038, no en 2106.
Bueno, en lo que respecta a El Capitan 10.11.6, la respuesta no es tan fácil como usar el script Perl.
Si intentamos esto
macmladen@buk $ touch -t 205012121212 my
macmladen@buk $ ls -al
total 104
drwx------ 7 root root 4096 Dec 25 13:42 .
drwxr-xr-x 23 root root 4096 Dec 4 17:06 ..
-rw-r--r-- 1 root root 0 Dec 12 2050 my
Eso demuestra que macOS en la capa más baja del sistema está a salvo del error Y2038. Eso significa que el sistema como tal no fallará y funcionará correctamente.
Sin embargo, a nivel de aplicación, ese no es siempre el caso.
Al intentar impulsar la fecha a 2040, las preferencias del sistema Fecha y hora respondieron configurándolo en 01.01.2038 (tendrá que desmarcar la configuración automática)
Eso significa que depende de la aplicación, cómo reaccionarán al error Y2038.
El Capitán no es susceptible:
#!/usr/bin/perl
use POSIX;
$ENV{'TZ'} = "GMT";
for ($clock = 2147483641; $clock < 2147483651; $clock++)
{
print ctime($clock);
}
Este script de perl proporciona el siguiente resultado:
Family-iMac:~ dude$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G1004
Family-iMac:~ dude$ /Users/dude/Desktop/2038.pl
Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:08 2038
Tue Jan 19 03:14:09 2038
Tue Jan 19 03:14:10 2038
La información recopilada y el guión compactado al mínimo de este sitio muy interesante .
Micro máquina
Forja del Trueno
Micro máquina