From 0f9cda3eb8afd89a9a2470d9a4c19a5c1c69b092 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Sat, 31 Aug 2024 12:24:59 +0200 Subject: streamline locale and timezone handling --- lib/Object/Groupware.pm | 37 ++++++++++++++++++++++++++ lib/Object/Groupware/Calendar.pm | 12 +++++++-- lib/Object/Groupware/DAV.pm | 14 +++++----- lib/Object/Groupware/Event.pm | 57 +++++++++++++++++++++++++++------------- 4 files changed, 93 insertions(+), 27 deletions(-) create mode 100644 lib/Object/Groupware.pm (limited to 'lib/Object') diff --git a/lib/Object/Groupware.pm b/lib/Object/Groupware.pm new file mode 100644 index 0000000..083f415 --- /dev/null +++ b/lib/Object/Groupware.pm @@ -0,0 +1,37 @@ +use v5.36; +use Feature::Compat::Class 0.07; + +package Object::Groupware 0.01; + +class Object::Groupware; + +use utf8; + +use Log::Any qw( ); + +field $log = Log::Any->get_logger; + +field $dt_locale : param : reader = undef; +field $dt_time_zone : param : reader = undef; +field $dt_span_time_prefix : param : reader = ''; + +ADJUST { + if ( defined $self->dt_locale ) { + $dt_locale = DateTime::Locale->load( $self->dt_locale ) + unless $self->dt_locale isa DateTime::Locale::FromData; + $log->debugf( + 'Class %s set up to use locale %s (%s)', + __CLASS__, $self->dt_locale->code, $self->dt_locale->name + ); + } + if ( defined $self->dt_time_zone ) { + $dt_time_zone = DateTime::TimeZone->new( name => $self->dt_time_zone ) + unless $self->dt_time_zone isa DateTime::TimeZone; + $log->debugf( + 'Class %s set up to use time zone %s', + __CLASS__, $self->dt_time_zone->name + ); + } +} + +1; diff --git a/lib/Object/Groupware/Calendar.pm b/lib/Object/Groupware/Calendar.pm index 7226782..386a749 100644 --- a/lib/Object/Groupware/Calendar.pm +++ b/lib/Object/Groupware/Calendar.pm @@ -3,7 +3,7 @@ use Feature::Compat::Class 0.07; package Object::Groupware::Calendar 0.01; -class Object::Groupware::Calendar; +class Object::Groupware::Calendar : isa(Object::Groupware); use utf8; @@ -39,7 +39,15 @@ method events ( $set = undef, $period = undef ) $set->start, $set->end ) if $set; - my @events = map { Object::Groupware::Event->new( entry => $_ ) } sort { + my $dt_locale = $self->dt_locale; + my $dt_time_zone = $self->dt_time_zone; + my @events = map { + Object::Groupware::Event->new( + entry => $_, + dt_locale => $dt_locale, + dt_time_zone => $dt_time_zone, + ) + } sort { $a->start->compare( $b->start ) || $a->start->compare( $b->start ) || $a->summary cmp $b->summary diff --git a/lib/Object/Groupware/DAV.pm b/lib/Object/Groupware/DAV.pm index 5c191e3..5dc789d 100644 --- a/lib/Object/Groupware/DAV.pm +++ b/lib/Object/Groupware/DAV.pm @@ -3,13 +3,12 @@ use Feature::Compat::Class 0.07; package Object::Groupware::DAV 0.01; -class Object::Groupware::DAV; +class Object::Groupware::DAV : isa(Object::Groupware); use utf8; use Feature::Compat::Try; -use POSIX qw(locale_h); # resolve LC_TIME -use locale; + use Net::Netrc; use IO::Interactive::Tiny; use Log::Any qw( ); @@ -20,9 +19,6 @@ use DateTime; use Object::Groupware::Calendar; -# use system locale to format DateTime objects parsed from iCal data -DateTime->DefaultLocale( setlocale(LC_TIME) ); - field $log = Log::Any->get_logger; field $uri : param; @@ -80,7 +76,11 @@ method get ($new_uri) # 3. PROPFIND with depth: 1 # as documented at - return Object::Groupware::Calendar->new( data => $session->cal ); + return Object::Groupware::Calendar->new( + data => $session->cal, + dt_locale => $self->dt_locale, + dt_time_zone => $self->dt_time_zone, + ); } 1; diff --git a/lib/Object/Groupware/Event.pm b/lib/Object/Groupware/Event.pm index 52fa143..c5ccb6e 100644 --- a/lib/Object/Groupware/Event.pm +++ b/lib/Object/Groupware/Event.pm @@ -3,50 +3,71 @@ use Feature::Compat::Class 0.07; package Object::Groupware::Event 0.01; -class Object::Groupware::Event; +class Object::Groupware::Event : isa(Object::Groupware); use utf8; use Log::Any qw( ); use Feature::Compat::Try; +use DateTime::Locale; field $log = Log::Any->get_logger; field $entry : param; +field $dt_locale; -field $begin : reader = $entry->start; -field $date_begin : reader = $begin->strftime('%A %e. %B'); -field $time_begin : reader = $begin->strftime('%k.%M'); -field $end : reader = $entry->end; -field $date_end : reader; -field $time_end : reader; +field $begin : reader = $entry->start; +field $end : reader = $entry->end; field $datespan : reader; field $timespan : reader; field $time_brief : reader; field $summary : reader = $entry->summary; -field $description : reader = $entry->description; +field $description : reader = $entry->description || ''; field $location : reader = $entry->_simple_property('location'); field $price : reader; field @attendees; field @attachments; ADJUST { - if ( defined $end ) { - $date_end = $end->strftime('%A %e. %B'); - $time_end = $end->strftime('%k.%M'); + if ( $self->dt_locale ) { + $dt_locale = $self->dt_locale; + $begin->set_locale($dt_locale); + $end->set_locale($dt_locale) if defined $end; + } + else { + + # we need the object regardless, to fetch CLDR patterns + $dt_locale = DateTime::Locale->load('en_US'); + } + + $begin->set_locale( $self->dt_locale ); + + for ( $self->dt_time_zone || () ) { + $begin->set_time_zone($_); + $end->set_time_zone($_) if defined $end; } $datespan - = ( defined $end and $date_end ne $date_begin ) - ? ucfirst("$date_begin - $date_end") - : ucfirst("$date_begin"); - $timespan - = ( defined $end and not $entry->all_day ) - ? ucfirst("$date_begin kl. $time_begin-$time_end") + = ( defined $end + and $end->clone->truncate( to => 'day' ) ne + $begin->clone->truncate( to => 'day' ) ) + ? ucfirst( + sprintf '%s - %s', + $begin->format_cldr( $dt_locale->date_format_medium() ), + $end->format_cldr( $dt_locale->date_format_medium() ) + ) + : ucfirst( $begin->format_cldr( $dt_locale->date_format_medium() ) ); + $timespan = ( defined $end and not $entry->all_day ) + ? ucfirst( + sprintf '%s-%s', + $begin->format_cldr( $dt_locale->datetime_format_medium() ), + $end->format_cldr( $dt_locale->time_format_medium() ) + ) : undef; $time_brief = $entry->all_day ? $datespan - : ucfirst("$date_begin kl. $time_begin"); + : ucfirst( + $begin->format_cldr( $dt_locale->datetime_format_medium() ) ); $description =~ s/\n\n[Pp]ris:\s*((?!\n).+)\s*\z//m; $price = $1; -- cgit v1.2.3