Objeto:
const DateTime = luxon.DateTime; userInfo = { startDate: '14/03/2022', startTime: '12:30', offsetShort: 'EDT', }De los documentos de Luxon , entendí que para obtener el valor de compensación , tengo que usar este método:
DateTime.fromObject(new Date(userInfo.startDate), {zone: 'America/New_York'}).toFormat('ZZ'); Devolverá el valor de compensación así: -05:00
Dado que mi api no devuelve el nombre de la zona (por ejemplo, América/Nueva_York), quiero obtener un valor de compensación basado en el nombre corto de compensación (es decir, IST, EST, EDT). ¿Alguna posibilidad en Luxon ?
Básicamente, necesito cualquiera de los siguientes resultados según el nombre corto compensado (EDT/EST/IST):
DateTime.fromObject(new Date('14-03-2022'), {zone: 'EDT'}).toFormat('ZZ'); >> -05:00 **OR** DateTime.fromObject(new Date('14-03-2022'), {zone: 'EDT'}).toFormat('ZZ'); >> America/New_YorkPara ilustrar aún más la dificultad aquí, he creado una función findPossibleIanaZones() . Esto tomará una abreviatura de zona horaria, por ejemplo, EST , EDT , IST y devolverá los nombres de zona horaria IANA coincidentes junto con el desplazamiento actual en minutos.
Como puede ver, obtendrá varios resultados coincidentes, aunque a menudo (¡ pero no siempre !) tendrán el mismo desplazamiento en minutos.
He usado moment-timezone y luxon para hacer esto, no puedo encontrar una solución solo para luxon.
También creé una función getOffsetForAbbreviation() , pero no siempre puede darnos un resultado inequívoco.
Como puede ver, IST puede referirse a la hora estándar de Irish Standard Time Israel Standard Time y, por supuesto India Standard Time .
function findPossibleIanaZones(zoneAbbreviation) { const timeZones = Object.values(moment.tz._zones).map(z => moment.tz.unpack(z)); const matchingZones = timeZones.filter(zone => zone.abbrs.includes(zoneAbbreviation)); return matchingZones.map(z => ({ name: z.name, currentUTCOffsetMinutes: getCurrentOffset(z.name )} )) } function getCurrentOffset(ianaZone) { return luxon.IANAZone.create(ianaZone).offset(Date.now()); } function getUTCOffset(ianaZone, unixTimeMs) { return luxon.IANAZone.create(ianaZone).offset(unixTimeMs); } function getOffsetForAbbreviation(unixTimeMs, zoneAbbreviation) { let zones = findPossibleIanaZones(zoneAbbreviation); let offsetNames = zones.map(zone => zone.name); let offsets = offsetNames.map(name => getUTCOffset(name, unixTimeMs)); let uniqueOffsets = [...new Set(offsets)]; // We should probably throw an error here, null will indicate no value found... if (uniqueOffsets.length !== 1) return null; return uniqueOffsets[0]; } const abbrs = ['EDT', 'EST', 'IST']; for(let abbr of abbrs) { console.log('Timezone abbreviation:', abbr, 'Result:', findPossibleIanaZones(abbr)); console.log('Current UTC offset:', getOffsetForAbbreviation(Date.now(), abbr)); } <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.0/luxon.min.js" integrity="sha512-2j5fkjQ4q5ceXgfxi+kqrU2Oz234MrpyywZsQz1F5OGnfat7mOhjRr0oz5cpQ+YwwWB+hhDBSyxNGuL/tKWMFw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>