[LON-CAPA-cvs] cvs: loncom /interface domainprefs.pm lonannounce.pm loncommon.pm lonparmset.pm /localize lonlocal.pm
raeburn
lon-capa-cvs-allow@mail.lon-capa.org
Fri, 19 Sep 2008 03:27:12 -0000
This is a MIME encoded message
--raeburn1221794832
Content-Type: text/plain
raeburn Thu Sep 18 23:27:12 2008 EDT
Modified files:
/loncom/interface loncommon.pm lonannounce.pm domainprefs.pm
lonparmset.pm
/loncom/localize lonlocal.pm
Log:
Bugs: 5792 and 5798.
- Uses DateTime, DateTime::Locale, DateTime::Locale::Catalog.
- Disposition of events in calendar display now consistent with current time zone.
- Timezone in effect is displayed in Calendar header line.
- First day of week determined from date localization in effect.
- Extra empty row eliminated from end of calendar.
- Default date localization can be set for domain from Default auth/language/timezone section of Domain Configuration.
- Date localization can also be set for a specific course via "Set Course environement".
- When in course context, course-specific date localization applies (if set), otherwise default date localization of domain of course (if set). In other contexts, date localization of domain of user (if set) applies.
- Currently date localization is only used to determine starting day of the week (for building calendar display). Future uses might consider date order/format for display of dates.
- &timehash() and &maketime() routines in loncommon.pm modified to use time zones.
- &nextday() routine in lonannounce.pm modified to correctly identify next day.
- &getdatelocale() routine added to lonlocal.pm to retrieve date locale object.
--raeburn1221794832
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20080918232712.txt"
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.686 loncom/interface/loncommon.pm:1.687
--- loncom/interface/loncommon.pm:1.686 Fri Sep 12 22:37:26 2008
+++ loncom/interface/loncommon.pm Thu Sep 18 23:27:04 2008
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.686 2008/09/13 02:37:26 raeburn Exp $
+# $Id: loncommon.pm,v 1.687 2008/09/19 03:27:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -69,6 +69,7 @@
use Apache::lonclonecourse();
use LONCAPA qw(:DEFAULT :match);
use DateTime::TimeZone;
+use DateTime::Locale::Catalog;
# ---------------------------------------------- Designs
use vars qw(%defaultdesign);
@@ -658,6 +659,57 @@
return $output;
}
+sub select_datelocale {
+ my ($name,$selected,$onchange,$includeempty)=@_;
+ my $output='<select name="'.$name.'" '.$onchange.'>'."\n";
+ if ($includeempty) {
+ $output .= '<option value=""';
+ if ($selected eq '') {
+ $output .= ' selected="selected" ';
+ }
+ $output .= '> </option>';
+ }
+ my (@possibles,%locale_names);
+ my @locales = DateTime::Locale::Catalog::Locales;
+ foreach my $locale (@locales) {
+ if (ref($locale) eq 'HASH') {
+ my $id = $locale->{'id'};
+ if ($id ne '') {
+ my $en_terr = $locale->{'en_territory'};
+ my $native_terr = $locale->{'native_territory'};
+ my @languages = &preferred_languages();
+ if (grep(/^en$/,@languages) || !@languages) {
+ if ($en_terr ne '') {
+ $locale_names{$id} = '('.$en_terr.')';
+ } elsif ($native_terr ne '') {
+ $locale_names{$id} = $native_terr;
+ }
+ } else {
+ if ($native_terr ne '') {
+ $locale_names{$id} = $native_terr.' ';
+ } elsif ($en_terr ne '') {
+ $locale_names{$id} = '('.$en_terr.')';
+ }
+ }
+ push (@possibles,$id);
+ }
+ }
+ }
+ foreach my $item (sort(@possibles)) {
+ $output.= '<option value="'.$item.'"';
+ if ($item eq $selected) {
+ $output.=' selected="selected"';
+ }
+ $output.=">$item";
+ if ($locale_names{$item} ne '') {
+ $output.=" $locale_names{$item}</option>\n";
+ }
+ $output.="</option>\n";
+ }
+ $output.="</select>";
+ return $output;
+}
+
=pod
=item * &linked_select_forms(...)
@@ -3354,16 +3406,21 @@
sub timehash {
- my @ltime=localtime(shift);
- return ( 'seconds' => $ltime[0],
- 'minutes' => $ltime[1],
- 'hours' => $ltime[2],
- 'day' => $ltime[3],
- 'month' => $ltime[4]+1,
- 'year' => $ltime[5]+1900,
- 'weekday' => $ltime[6],
- 'dayyear' => $ltime[7]+1,
- 'dlsav' => $ltime[8] );
+ my ($thistime) = @_;
+ my $timezone = &Apache::lonlocal::gettimezone();
+ my $dt = DateTime->from_epoch(epoch => $thistime)
+ ->set_time_zone($timezone);
+ my $wday = $dt->day_of_week();
+ if ($wday == 7) { $wday = 0; }
+ return ( 'second' => $dt->second(),
+ 'minute' => $dt->minute(),
+ 'hour' => $dt->hour(),
+ 'day' => $dt->day_of_month(),
+ 'month' => $dt->month(),
+ 'year' => $dt->year(),
+ 'weekday' => $wday,
+ 'dayyear' => $dt->day_of_year(),
+ 'dlsav' => $dt->is_dst() );
}
sub utc_string {
@@ -3373,6 +3430,24 @@
sub maketime {
my %th=@_;
+ my ($epoch_time,$timezone,$dt);
+ $timezone = &Apache::lonlocal::gettimezone();
+ eval {
+ $dt = DateTime->new( year => $th{'year'},
+ month => $th{'month'},
+ day => $th{'day'},
+ hour => $th{'hour'},
+ minute => $th{'minute'},
+ second => $th{'second'},
+ time_zone => $timezone,
+ );
+ };
+ if (!$@) {
+ $epoch_time = $dt->epoch;
+ if ($epoch_time) {
+ return $epoch_time;
+ }
+ }
return POSIX::mktime(
($th{'seconds'},$th{'minutes'},$th{'hours'},
$th{'day'},$th{'month'}-1,$th{'year'}-1900,0,0,-1));
Index: loncom/interface/lonannounce.pm
diff -u loncom/interface/lonannounce.pm:1.70 loncom/interface/lonannounce.pm:1.71
--- loncom/interface/lonannounce.pm:1.70 Sun May 18 15:45:46 2008
+++ loncom/interface/lonannounce.pm Thu Sep 18 23:27:04 2008
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Announce
#
-# $Id: lonannounce.pm,v 1.70 2008/05/18 19:45:46 www Exp $
+# $Id: lonannounce.pm,v 1.71 2008/09/19 03:27:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -38,6 +38,8 @@
use Apache::lonnet;
use HTML::Entities();
use LONCAPA qw(:match);
+use DateTime;
+use DateTime::TimeZone;
my %todayhash;
my %showedcheck;
@@ -292,11 +294,59 @@
}
sub nextday {
- my %th=@_;
- $th{'day'}++;
+ my ($tk,%th)=@_;
+ my ($incmonth,$incyear);
+ if ($th{'day'} > 27) {
+ if ($th{'month'} == 2) {
+ if ($th{'day'} == 29) {
+ $incmonth = 1;
+ } elsif ($th{'day'} == 28) {
+ if (!&is_leap_year($tk)) {
+ $incmonth = 1;
+ }
+ }
+ } elsif (($th{'month'} == 4) || ($th{'month'} == 6) ||
+ ($th{'month'} == 9) || ($th{'month'} == 11)) {
+ if ($th{'day'} == 30) {
+ $incmonth = 1;
+ }
+ } elsif ($th{'day'} == 31) {
+ if ($th{'month'} == 12) {
+ $incyear = 1;
+ } else {
+ $incmonth = 1;
+ }
+ }
+ if ($incyear) {
+ $th{'day'} = 1;
+ $th{'month'} = 1;
+ $th{'year'}++;
+ } elsif ($incmonth) {
+ $th{'day'} = 1;
+ $th{'month'}++;
+ } else {
+ $th{'day'}++;
+ }
+ } else {
+ $th{'day'}++;
+ }
return (&Apache::loncommon::maketime(%th),$th{'month'});
}
+sub is_leap_year {
+ my ($thistime) = @_;
+ my ($is_leap,$timezone,$dt);
+ $timezone = &Apache::lonlocal::gettimezone();
+ eval {
+ $dt = DateTime->from_epoch(epoch => $thistime)
+ ->set_time_zone($timezone);
+ };
+ if (!$@) {
+ $is_leap = $dt->is_leap_year;
+ }
+ return $is_leap;
+}
+
sub display_msg {
my ($msg) = @_;
@@ -323,7 +373,7 @@
sub showday {
my ($tk,$mode,%allcal)=@_;
my %th=&Apache::loncommon::timehash($tk);
- my ($nextday,$nextmonth)=&nextday(%th);
+ my ($nextday,$nextmonth)=&nextday($tk,%th);
my @outp;
if ($mode) {
my $oneday=24*3600;
@@ -415,6 +465,13 @@
$r->print("END:VCALENDAR$crlf");
}
+sub show_timezone {
+ my $tzone = &Apache::lonlocal::gettimezone();
+ my $dt = DateTime->now();
+ my $tz = DateTime::TimeZone->new( name => $tzone );
+ return &mt('([_1] time zone)',$tz->short_name_for_datetime($dt));
+}
+
sub handler {
my $r = shift;
if ($r->uri=~/\.(ics|ical)$/) {
@@ -446,12 +503,15 @@
'&element='.$env{'form.element'};
# --------------------------------------------- Find out first day of the month
- my %firstday=&Apache::loncommon::timehash(
- &Apache::loncommon::maketime( 'day' => 1, 'month'=> $month,
- 'year' => $year, 'hours' => 0,
- 'minutes' => 0, 'seconds' => 0,
- 'dlsav' => -1 ));
+ my $tk = &Apache::loncommon::maketime( 'day' => 1,
+ 'month'=> $month,
+ 'year' => $year,
+ 'hour' => 0,
+ 'minute' => 0,
+ 'second' => 0);
+ my %firstday = &Apache::loncommon::timehash($tk);
my $weekday=$firstday{'weekday'};
+
# ------------------------------------------------------------ Print the screen
my $js = <<ENDDOCUMENT;
<script type="text/javascript">
@@ -585,7 +645,7 @@
&mt('June'),&mt('July'),&mt('August'),
&mt('September'),&mt('October'),
&mt('November'),&mt('December'))[$month].' '.
- $year.'</h1>');
+ $year.' '.&show_timezone().'</h1>');
# Reached the end of times, give up
if (($year<1970) || ($year>2037)) {
$r->print('<h3>No calendar available for this date.</h3>'.
@@ -599,6 +659,35 @@
if ($env{'form.pickdate'} eq 'yes') {
$class .= " LC_calendar_pickdate";
}
+# ------------------------------------------------ Determine first day of a week
+ my $datelocale = &Apache::lonlocal::getdatelocale();
+ my $days_in_week = 7;
+ my $startweek = 0;
+ if (ref($datelocale)) {
+ $startweek = $datelocale->first_day_of_week();
+ if ($startweek == $days_in_week) { $startweek = 0; }
+ }
+ my @days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
+ my @localdays;
+ if ($startweek == 0) {
+ @localdays = @days;
+ } else {
+ my $endday = $days_in_week - $startweek;
+ for (my $i=0; $i<$days_in_week; $i++) {
+ if ($i < $endday) {
+ $localdays[$i] = $days[$i+$startweek];
+ } else {
+ $localdays[$i] = $days[$i-$endday];
+ }
+ }
+ }
+
+# ----------------------------------------------------------- Weekday in locale
+ my $loc_weekday = $weekday - $startweek;
+ if ($loc_weekday < 0) {
+ $loc_weekday += $days_in_week;
+ }
+
$r->print(
'<a href="/adm/announcements?month='.$pm.'&year='.$py.
($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '.
@@ -607,14 +696,11 @@
' <a href="/adm/announcements?month='.$todayhash{'month'}.
'&year='.$todayhash{'year'}.
($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a><p>'.
- '<table class="'.$class.'" cols="7" rows="5"><tr>
-<th>'.&mt('Sun').'</th>
-<th>'.&mt('Mon').'</th>
-<th>'.&mt('Tue').'</th>
-<th>'.&mt('Wed').'</th>
-<th>'.&mt('Thu').'</th>
-<th>'.&mt('Fri').'</th>
-<th>'.&mt('Sat').'</th></tr>');
+ '<table class="'.$class.'" cols="7" rows="5"><tr>');
+ for (my $i=0; $i<@localdays; $i++) {
+ $r->print('<th>'.&mt($localdays[$i]).'</th>');
+ }
+ $r->print('</tr>');
my $tk=&Apache::loncommon::maketime(%firstday);
my $outp;
@@ -622,21 +708,33 @@
# ---------------------------------------------------------------- Actual table
$r->print('<tr>');
- for (my $i=0;$i<$weekday;$i++) { $r->print(&emptycell); }
- for (my $i=$weekday;$i<=6;$i++) {
+ for (my $i=0;$i<$loc_weekday;$i++) { $r->print(&emptycell); }
+ for (my $i=$loc_weekday;$i<=6;$i++) {
($tk,$nm,$outp)=&showday($tk,0,%allcal);
$r->print($outp);
}
$r->print('</tr>');
+ my $lastrow = 0;
+ my $lastday = 0;
for (my $k=0;$k<=4;$k++) {
- $r->print('<tr>');
- for (my $i=0;$i<=6;$i++) {
- ($tk,$nm,$outp)=&showday($tk,0,%allcal);
- if ($month!=$nm) { $outp=&emptycell; }
- $r->print($outp);
+ if (!$lastrow) {
+ $r->print('<tr>');
+ for (my $i=0;$i<=6;$i++) {
+ if ($lastday) {
+ $outp = &emptycell();
+ } else {
+ my $currtk = $tk;
+ ($tk,$nm,$outp)=&showday($tk,0,%allcal);
+ if ($month!=$nm) { $lastday = 1; }
+ }
+ $r->print($outp);
+ }
+ if ($lastday) {
+ $lastrow = 1;
+ }
+ $r->print('</tr>');
}
- $r->print('</tr>');
}
# ------------------------------------------------------------------- End table
$r->print('</table>');
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.67 loncom/interface/domainprefs.pm:1.68
--- loncom/interface/domainprefs.pm:1.67 Tue Jul 22 22:50:57 2008
+++ loncom/interface/domainprefs.pm Thu Sep 18 23:27:04 2008
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set domain-wide configuration settings
#
-# $Id: domainprefs.pm,v 1.67 2008/07/23 02:50:57 raeburn Exp $
+# $Id: domainprefs.pm,v 1.68 2008/09/19 03:27:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -42,6 +42,7 @@
use File::Copy;
use Locale::Language;
use DateTime::TimeZone;
+use DateTime::Locale;
sub handler {
my $r=shift;
@@ -1823,7 +1824,8 @@
sub print_defaults {
my ($dom,$rowtotal) = @_;
- my @items = ('auth_def','auth_arg_def','lang_def','timezone_def');
+ my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
+ 'datelocale_def');
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
my $titles = &defaults_titles();
my $rownum = 0;
@@ -1858,6 +1860,9 @@
} elsif ($item eq 'timezone_def') {
my $includeempty = 1;
$datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty);
+ } elsif ($item eq 'datelocale_def') {
+ my $includeempty = 1;
+ $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty);
} else {
$datatable .= '<input type="text" name="'.$item.'" value="'.
$domdefaults{$item}.'" />';
@@ -1875,6 +1880,7 @@
'auth_arg_def' => 'Default authentication argument',
'lang_def' => 'Default language',
'timezone_def' => 'Default timezone',
+ 'datelocale_def' => 'Default locale for dates',
);
return (\%titles);
}
@@ -4251,7 +4257,7 @@
my ($dom,$r) = @_;
my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
- my @items = ('auth_def','auth_arg_def','lang_def','timezone_def');
+ my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def');
my @authtypes = ('internal','krb4','krb5','localauth');
foreach my $item (@items) {
$newvalues{$item} = $env{'form.'.$item};
@@ -4278,6 +4284,13 @@
push(@errors,$item);
}
}
+ } elsif ($item eq 'datelocale_def') {
+ if ($newvalues{$item} ne '') {
+ my @datelocale_ids = DateTime::Locale->ids();
+ if (!grep(/^\Q$newvalues{$item}\E$/,@datelocale_ids)) {
+ push(@errors,$item);
+ }
+ }
}
if (grep(/^\Q$item\E$/,@errors)) {
$newvalues{$item} = $domdefaults{$item};
@@ -4290,6 +4303,7 @@
auth_arg_def => $newvalues{'auth_arg_def'},
lang_def => $newvalues{'lang_def'},
timezone_def => $newvalues{'timezone_def'},
+ datelocale_def => $newvalues{'datelocale_def'},
}
);
my $title = &defaults_titles();
@@ -4322,7 +4336,7 @@
my $cachetime = 24*60*60;
&Apache::lonnet::do_cache_new('domdefaults',$dom,
$defaults_hash{'defaults'},$cachetime);
- if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'}) {
+ if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {
my $sysmail = $r->dir_config('lonSysEMail');
&Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext);
}
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.408 loncom/interface/lonparmset.pm:1.409
--- loncom/interface/lonparmset.pm:1.408 Thu Aug 28 00:42:27 2008
+++ loncom/interface/lonparmset.pm Thu Sep 18 23:27:04 2008
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set parameters for assessments
#
-# $Id: lonparmset.pm,v 1.408 2008/08/28 04:42:27 raeburn Exp $
+# $Id: lonparmset.pm,v 1.409 2008/09/19 03:27:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -2357,6 +2357,8 @@
'categories'
=> '<b>'.&mt('Categorize course').'</b> <a href="javascript:catsbrowser()">'.
&mt('Display Categories').'</a>',
+ 'datelocale'
+ => '<b>'.&mt('Locale used for course calendar').'</b>',
);
my @Display_Order = ('url','description','courseid','cloners');
(my $can_toggle_cat,$can_categorize) = &can_modify_catsettings($dom);
@@ -2380,6 +2382,7 @@
'allow_discussion_post_editing',
'languages',
'timezone',
+ 'datelocale',
'nothideprivileged',
'rndseed',
'receiptalg',
@@ -2433,6 +2436,17 @@
&Apache::loncommon::select_timezone($parameter.'_value',
$timezone,
$onchange,$includeempty).'</td>';
+ } elsif ($parameter eq 'datelocale') {
+ my $includeempty = 1;
+ my $locale_obj = &Apache::lonlocal::getdatelocale();
+ my $currdatelocale;
+ if (ref($locale_obj)) {
+ $currdatelocale = $locale_obj->id();
+ }
+ $output .= '<td>'.
+ &Apache::loncommon::select_datelocale($parameter.'_value',
+ $currdatelocale,
+ $onchange,$includeempty).'</td>';
} elsif ($parameter eq 'categories') {
my $catdisplay;
if ($values{'categories'} ne '') {
Index: loncom/localize/lonlocal.pm
diff -u loncom/localize/lonlocal.pm:1.48 loncom/localize/lonlocal.pm:1.49
--- loncom/localize/lonlocal.pm:1.48 Fri Sep 12 22:37:29 2008
+++ loncom/localize/lonlocal.pm Thu Sep 18 23:27:04 2008
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Localization routines
#
-# $Id: lonlocal.pm,v 1.48 2008/09/13 02:37:29 raeburn Exp $
+# $Id: lonlocal.pm,v 1.49 2008/09/19 03:27:04 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -166,6 +166,7 @@
use POSIX qw(locale_h strftime);
use DateTime();
use DateTime::TimeZone;
+use DateTime::Locale;
require Exporter;
@@ -366,6 +367,38 @@
}
}
+sub getdatelocale {
+ my ($datelocale,$locale_obj);
+ if ($Apache::lonnet::env{'course.'.$Apache::lonnet::env{'request.course.id'}.'.datelocale'}) {
+ $datelocale = $Apache::lonnet::env{'course.'.$Apache::lonnet::env{'request.course.id'}.'.datelocale'};
+ } elsif ($Apache::lonnet::env{'request.course.id'} ne '') {
+ my $cdom = $Apache::lonnet::env{'course.'.$Apache::lonnet::env{'request.course.id'}.'.domain'};
+ if ($cdom ne '') {
+ my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
+ if ($domdefaults{'datelocale_def'} ne '') {
+ $datelocale = $domdefaults{'datelocale_def'};
+ }
+ }
+ } elsif ($Apache::lonnet::env{'user.domain'} ne '') {
+ my %udomdefaults = &Apache::lonnet::get_domain_defaults($Apache::lonnet::env{'user.domain'});
+ if ($udomdefaults{'datelocale_def'} ne '') {
+ $datelocale = $udomdefaults{'datelocale_def'};
+ }
+ }
+ if ($datelocale ne '') {
+ eval {
+ $locale_obj = DateTime::Locale->load($datelocale);
+ };
+ if (!$@) {
+ if ($locale_obj->id() eq $datelocale) {
+ return $locale_obj;
+ }
+ }
+ }
+ return $locale_obj;
+}
+
+
# ==================== Normalize string (reduce fragility in the lexicon files)
# This normalizes a string to reduce fragility in the lexicon files of
--raeburn1221794832--