Nano Hash - криптовалюты, майнинг, программирование

Perl Data::ICal выводит время события как T000000Z вместо его пропуска

Я пытаюсь создать канал ICal, используя Data:ICal, но некоторые события печатаются без указания времени. Я читал, что время не требуется, если оно равно 000000, но Календарь Google не обрабатывает эти события без времени должным образом.

Вот пример скрипта и вывода. Мне нужно, чтобы вывод был в часовом поясе UTC.

#!/usr/bin/perl -w
use strict;
use Date::ICal;
use Data::ICal;
use Data::ICal::Entry::Event;
use DateTime;
use Data::Dumper;

sub get_utc_offset($) {
    my ($orig_tz_str) = @_;

    # Using a set winter date to avoid problems with daylight savings time
    my $utc_compare_datetime = DateTime->new(
        year      => 2012,
        month     => 1,
        day       => 1,
        hour      => 1,
        minute    => 1,
        time_zone => 'UTC'
    );

    my $tz             = DateTime::TimeZone->new(name => $orig_tz_str);
    my $utc_offset     = $tz->offset_for_datetime($utc_compare_datetime);
    my $utc_offset_str = DateTime::TimeZone->offset_as_string($utc_offset);

    return $utc_offset_str;
}

sub add_ical_event($$$$$$) {
    my ($calendar, $start, $end, $summary, $description, $timezone) = @_;
    my $offset   = get_utc_offset($timezone);
    $description = 'none' if (!$description);

    my $event = Data::ICal::Entry::Event->new();
    $event->add_properties(
        summary     => $summary,
        description => $description,
        dtstart     => Date::ICal->new( ical  => $start, offset => $offset )->ical,
        dtend       => Date::ICal->new( ical  => $end,   offset => $offset )->ical,
        dtstamp     => Date::ICal->new( epoch => time                      )->ical
    );
    $calendar->add_entry($event);
}


# Tests
# ----------------------------------------------------------------------------

my $timezone = 'America/New_York';

my $calendar = Data::ICal->new();
$calendar->add_properties(
    method         => "PUBLISH",
    prodid         => "-//Test Cal//NONSGML Calendar//EN",
    'X-WR-CALNAME' => 'Test Cal'
);

my (%events) = (
    1 => {
        summary     => 'Test Shift Tool - Testing Shift',
        description => '',
        start       => '20130828T160000',
        end         => '20130828T190000',
        timezone    => $timezone
    },
    2 => {
        summary     => 'New Member Meeting',
        description => '',
        start       => '20130722T190000',
        end         => '20130722T210000',
        timezone    => $timezone
    },
    3 => {
        summary     => 'public',
        description => '',
        start       => '20130630T130000',
        end         => '20130630T140000',
        timezone    => $timezone
    }
);
foreach my $key (sort keys %events) {
    my $e = $events{$key};
    add_ical_event(
        $calendar,
        $e->{start},
        $e->{end},
        $e->{summary},
        $e->{description},
        $e->{timezone}
    );
}
print $calendar->as_string;

Обратите внимание, что некоторые события имеют дату начала или окончания без указания времени. Когда я вручную добавляю T000000Z, эти события правильно импортируются в Календарь Google. Любые предложения о том, как заставить все события иметь время?

BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:-//Digital Cheetah//NONSGML Calendar//EN
X-WR-CALNAME:Digital Cheetah
BEGIN:VEVENT
DESCRIPTION:none
DTEND:20130829Z
DTSTAMP:20130823T214317Z
DTSTART:20130828T210000Z
SUMMARY:Test Shift Tool - Testing Shift
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:none
DTEND:20130723T020000Z
DTSTAMP:20130823T214317Z
DTSTART:20130723Z
SUMMARY:New Member Meeting
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:none
DTEND:20130630T190000Z
DTSTAMP:20130823T214317Z
DTSTART:20130630T180000Z
SUMMARY:public
END:VEVENT
END:VCALENDAR

Ответы:


1

Я читал, что время не требуется, если оно 000000

Это не то, что говорится в RFC. Обратимся к следующим разделам:

  • 4.3.4 Дата
  • 4.3.5 Дата-время
  • 4.8.7.2 Дата/время

Я приведу соответствующие спецификации формата здесь:

date               = date-value

date-value         = date-fullyear date-month date-mday
date-fullyear      = 4DIGIT

date-time  = date "T" time ;As specified in the date and time
                             ;value definitions

dtstamp    = "DTSTAMP" stmparam ":" date-time CRLF

Когда ваш вывод включает DTSTAMP, спецификация ICal ожидает, что за ним следует date-time.

Что приводит нас к Date::ICal и его методу ical. Возвращает ли iCal date или date-time? Как оказалось, он пытается угадать, какой формат вам нужен, проверяя, имеет ли ваша временная метка время 000000. Убедитесь сами в строке 286 файла ICal.pm< /а>.

Возможно, мы ожидаем, что Data::ICal::Entry справится с этим сценарием. Я мог бы пропустить код проверки на этом конце, но на данный момент я не вижу ничего, что явно имело бы значение. Похоже, он принимает значения свойств, не проверяя их.

В зависимости от вашей точки зрения это звучит как ошибка или ограничение библиотек.

Итак... как это исправить? В идеале одна из этих библиотек, вероятно, должна проверять и обрабатывать этот сценарий. А пока вам нужно встать на ноги:

Быстрое и грязное исправление: если ваше время равно нулю, увеличьте его на одну секунду; ical теперь будет возвращать допустимую, но немного неточную строку date-time.

Немного лучше: проверьте возвращаемое значение из ical; если это date, переформатируйте его как date-time.

Проверьте это перед использованием, но, возможно, что-то вроде этого:

dtstart => $ical =~ s/(\d{8})Z/$1T000000Z/r;
23.08.2013
  • Спасибо за подробное объяснение. В итоге я сделал замену после преобразования в UTC, и это отлично работает. 26.08.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..