Создайте ics с динамическим VTIMEZONE, используя момент js

Попытка создать файл .ics с компонентом VTIMEZONE, который на основе предоставленного часового пояса динамически устанавливает стандартное время и летнее время.

Просто образец:

BEGIN:VTIMEZONE
TZID:America/New_York
LAST-MODIFIED:20050809T050000Z
BEGIN:STANDARD
DTSTART:20071104T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20070311T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE

Пытаясь решить эту проблему, я создал moment.tz.zone(timezone)Object, основанный на документации момента https://momentjs.com/timezone/docs/#/zone-object/ Я предполагаю, что содержит необходимые данные untils (должны быть TZOFFSETFROM, TZOFFSETTO) и offsets (DTSTART).

Тем не менее, я не могу найти четкую документацию о том, как извлечь эти данные.

Было интересно, можно ли в любом случае извлечь DTSTART, TZOFFSETFROM и TZOFFSETTO для стандартного времени и дневного света в moment-timezone.js


person Road2PreSchool    schedule 05.02.2019    source источник


Ответы (2)


Как вы уже упоминали в вопросе, вы можете использовать moment.tz.zone(name). Это даст вам объект Zone, который содержит список временных меток в свойстве untils, затем вы можете применить свою логику для получения нужных временных меток в VTIMEZONE (я использовал первые временные метки массива untils в своем примере кода) .

Вы можете использовать moment.tz и format() на отметке времени, чтобы получить DTSTART. Вы можете передать токен ZZ в format(), чтобы получить смещение для TZOFFSETFROM и TZOFFSETTO.

Вы можете использовать значения abbrs, чтобы получить TZNAME.

Вот живой образец:

const MAX_OCCUR = 2;
const getVtimezoneFromMomentZone = (tzName) => {
  const zone = moment.tz.zone(tzName);
  const header = `BEGIN:VTIMEZONE\nTZID:${tzName}`;
  const footer = 'END:VTIMEZONE';
  
  let zTZitems = '';
  for(let i=0; i<MAX_OCCUR && i+1<zone.untils.length; i++){
    const type = i%2 == 0 ? 'STANDARD' : 'DAYLIGHT';
    const momDtStart = moment.tz(zone.untils[i], tzName);
    const momNext = moment.tz(zone.untils[i+1], tzName);
    const item = 
`BEGIN:${type}
DTSTART:${momDtStart.format('YYYYMMDDTHHmmss')}
TZOFFSETFROM:${momDtStart.format('ZZ')}
TZOFFSETTO:${momNext.format('ZZ')}
TZNAME:${zone.abbrs[i]}
END:${type}\n`;
    zTZitems += item;
  }
  const result = `${header}\n${zTZitems}${footer}\n`;
  return result;
};

console.log(getVtimezoneFromMomentZone('America/New_York'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>

person VincenzoC    schedule 06.02.2019
comment
После небольшого тестирования выяснилось, что эта функция возвращает неправильный часовой пояс для Европы/Мадрида (пока не удалось понять, почему) - person apnerve; 23.10.2019

Вы можете скачать готовые компоненты VTIMEZONE здесь:

http://tzurl.org/

person Michael    schedule 06.02.2019
comment
Однако обратите внимание, что между обновлениями базы данных IANA и часовых поясов, доступных здесь, часто возникает задержка: например, в настоящее время отстает на 4 версии. Также обратите внимание, что он действительно синхронизирован с проектом vzic, поэтому некоторые часовые пояса могут быть неправильно преобразованы :-( - person jcaron; 10.07.2019