¿Cómo obtengo nombres de Rails TimeZone a partir de identificadores TZInfo obsoletos?

Ya hay una pregunta que responde cómo convertir “América / Los_Angeles” a “Hora del Pacífico (EE. UU. Y Canadá)”. Sin embargo, quiero convertir “US / Pacific” y otras zonas horarias obsoletas a Rails TimeZone. No puedo encontrar nada en la biblioteca que me ayude a lograr esto.

Desde los documentos de Rails ActiveSupport :: TimeZone :

La versión de TZInfo incluida con Active Support solo incluye las definiciones necesarias para admitir las zonas definidas por la clase TimeZone. Si necesita usar zonas que no estén definidas por TimeZone, deberá instalar la gem TZInfo (si se instala localmente una versión reciente de la gem, se usará esto en lugar de la versión incluida).

Personalmente, creo que las zonas horarias de Rails son tontas. Se limitan arbitrariamente a lo que Rails describe como “un subconjunto significativo de 146 zonas”. Pero no hacen nada para explicar cómo determinan qué zonas son “significativas” y cuáles se descartan.

Los identificadores como “US / Pacific” se conocen como “enlaces” o “alias” en los datos de TZDB. Pude ver que tal vez podrían omitirse en Rails, pero hay muchas otras zonas horarias del mundo real que faltan por completo.

El único lugar donde he visto todos los identificadores de zonas horarias de Rails en el mundo real es en la API de Twitter. Por otro lado, los identificadores IANA / TZDB son ubicuos.

El mejor consejo que puedo ofrecer es olvidarse de las zonas horarias de Rails y simplemente usar la gem Ruby TZInfo directamente. Tiene la implementación completa de TZDB con todas las zonas, incluidos los alias.

Si realmente debe continuar usando las zonas de Rails, primero podría usar TZInfo para resolver el alias de la zona real, y luego ver si esa zona está en el diccionario MAPPING Rails. Por ejemplo:

 "US/Pacific" => "America/Los_Angeles" (via TZInfo) "America/Los_Angeles" => "Pacific Time (US & Canada)" (via Rails MAPPING) 

Creo que cuando cargue “US / Pacific” a través de TZInfo, se subclasificará como un objeto LinkedTimezoneInfo , por lo que podría usar el atributo link_to_identifier desde allí.

En este comando se mostrarán los 144 nombres de zona horaria.

ActiveSupport :: TimeZone.zones_map

Puedes hacerlo por esto:

 arr = TZInfo::Timezone.all_country_zone_identifiers.collect { |x| x + " " + ActiveSupport::TimeZone[x].formatted_offset } arr.sort