Re: Localized weekday names
by hippo (Archbishop) on Nov 02, 2017 at 11:55 UTC
|
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
use POSIX;
my @days = Time::Piece->day_list;
print "Days are @days\n";
setlocale( LC_ALL, 'fr_FR' );
Time::Piece->use_locale ();
@days = Time::Piece->day_list;
print "Days are @days\n";
$ perl days.pl
Days are Sun Mon Tue Wed Thu Fri Sat
Days are dim. lun. mar. mer. jeu. ven. sam.
| [reply] [d/l] [select] |
|
I suspect I have some different version of Time::Piece than what you have:
mcp:~>perl days.pl
Can't locate object method "use_locale" via package "Time::Piece" at d
+ays.pl line 10.
and if I remove the "use_locale" line, I get this interesting result:
Days are Sun Mon Tue Wed Thu Fri Sat
Days are Time::Piece
I must admit, I have no clue why the second call to Time::Piece does not work anymore.
Versions are:
p5-Time-Piece-1.23_1 Time::Piece - Object Oriented time obje
+cts
This is perl 5, version 24, subversion 3 (v5.24.3) built for amd64-fre
+ebsd-thread-multi
Last, but not least, Time::Piece apparently does not care for the locale by default:
mcp:~>LC_TIME=de_DE.UTF-8 perl -MTime::Piece -le 'print join",",Time::
+Piece->day_list'
Sun,Mon,Tue,Wed,Thu,Fri,Sat
| [reply] [d/l] [select] |
|
p5-Time-Piece-1.23_1
Time::Piece 1.23 is over 4 years old. That really doesn't count as "recent" so no, you would need to upgrade it to take advantage of the new features (and bug fixes and stability improvements and ...). My script was tested against version 1.31_04 which is more modern and the current version is 1.3202 from about 6 weeks ago.
Last, but not least, Time::Piece apparently does not care for the locale by default
This is precisely why the newer versions have use_locale :-)
| [reply] [d/l] |
Re: Localized weekday names
by 1nickt (Canon) on Nov 02, 2017 at 12:09 UTC
|
Hi,
Not sure why you don't want to use library modules. I do, so I am not an expert on POSIX native functions or their Perl implementation. But I do see in the doc for POSIX::strftime:
... the results of some of the conversion specifiers are non-portable. For example, the specifiers aAbBcpZ change according to the locale settings of the user, and both how to set locales (the locale names) and what output to expect are non-standard.
Easy with DateTime (and you don't need to muck around with changing the system locale):
$ perl -MDateTime -E 'say DateTime->from_epoch(epoch => time + $_ * 86
+400, locale => "fr")->day_name for (0..6)'
jeudi
vendredi
samedi
dimanche
lundi
mardi
mercredi
Hope this helps!
The way forward always starts with a minimal test.
| [reply] [d/l] |
|
perl -MDateTime -le '@wd=map {DateTime->new(locale=> "de", year=>1970,
+month=>1,day=>4+$_)->strftime("%a")} (0..6);print join",",@wd'
Which does work, but for Germany this interestingly produces
So.,Mo.,Di.,Mi.,Do.,Fr.,Sa.
instead of the desired
So,Mo,Di,Mi,Do,Fr,Sa
It doesn't look like DateTime can handle %a returning only 2 chars. -- No Idea why :-) | [reply] [d/l] [select] |
|
Abbreviated (format)
Mo.
Di.
Mi.
Do.
Fr.
Sa.
So.
...
Abbreviated (stand-alone)
Mo
Di
Mi
Do
Fr
Sa
So
So you should use DateTime::format_cldr() with format ccc to print "Abbreviated (stand-alone)", as shown in the docs:
$ perl -Mstrict -MDateTime -wlE 'say join", ", map { DateTime->new( lo
+cale => "de", year => 1970, month => 1, day => 4 + $_ )->format_cldr(
+"ccc") } 0 .. 6'
So, Mo, Di, Mi, Do, Fr, Sa
The way forward always starts with a minimal test.
| [reply] [d/l] [select] |
Re: Localized weekday names
by choroba (Cardinal) on Nov 02, 2017 at 17:31 UTC
|
Are you sure it's ever worked? As far as I remember the weekday has always been ignored.
In my version of strftime, negative month day is ok, so the fix is easy: just subtract the week day from the month day:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use POSIX qw( locale_h strftime );
setlocale( LC_TIME, 'fr_FR' );
my @date = localtime;
$date[3] -= $date[6];
my @wd = map {
$date[3]++;
strftime '%A', @date
} 0 .. 6;
print "@wd\n";
Note that a single array element is written $date[6], without the at-sign.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
Hi,
I know it worked at one point several years ago. It might've been an older version of FreeBSD having a different strftime implementation.
And yes, you are completely right calling out the @date[6] mistake. I should know better - to my defense, that code is really old :)
And yes, your "hack" works great. This enabled me to "fix" it with minimal changes.
Thanks!
| [reply] [d/l] |
Re: Localized weekday names
by thanos1983 (Parson) on Nov 02, 2017 at 11:58 UTC
|
Hello Sec,
By "the list of weekdays in a particular local" you mean working days? If so there is a similar question How to find business days?. If not can you tell us a bit more regarding the days that you are trying to retrieve?
Update: If you simply you want to calculate the days from today to another day you can do it with Date::Manip, sample of code below:
#!/usr/bin/perl
use strict;
use warnings;
use Date::Manip;
use feature 'say';
my $tz = new Date::Manip::TZ;
my $dateLocal = ParseDate('now');
my $unixLocal = UnixDate($dateLocal,'%A');
say $unixLocal;
my $delta = ParseDateDelta("4 days later");
my $date = DateCalc($dateLocal, $delta);
my $newDate = UnixDate($date,'%A');
say $newDate;
__END__
$ perl test.pl
Thursday
Monday
Update2: If you want to calculate the working days you can do it like this:
#!/usr/bin/perl
use strict;
use warnings;
use Date::Manip;
use feature 'say';
my $tz = new Date::Manip::TZ;
my $dateLocal = ParseDate('now');
my $unixLocal = UnixDate($dateLocal,'%A');
say $unixLocal;
my $date = DateCalc($dateLocal, "4 days earlier");
my $newDate = UnixDate($date,'%A');
say $newDate;
my $businessDeltaMinus = DateCalc($dateLocal,"-4 business days");
my $workingDateMinus = UnixDate($businessDeltaMinus,'%A');
say $workingDateMinus;
my $businessDeltaPlus = DateCalc($dateLocal,"+4 business days");
my $workingDatePlus = UnixDate($businessDeltaPlus,'%A');
say $workingDatePlus;
__END__
$ perl test.pl
Thursday
Sunday
Friday
Wednesday
Update3: If you want one liner solution, sample below:
#!/usr/bin/perl
use strict;
use warnings;
use Date::Manip;
use feature 'say';
my $tz = new Date::Manip::TZ;
say UnixDate(DateCalc(
ParseDate('today'),
$_ . " days later") , '%A') for (1..7);
__END__
$ perl test.pl
Friday
Saturday
Sunday
Monday
Tuesday
Wednesday
Thursday
Update4: In case you want business days, sample below:
#!/usr/bin/perl
use strict;
use warnings;
use Date::Manip;
use feature 'say';
my $tz = new Date::Manip::TZ;
say UnixDate(DateCalc(
ParseDate('today'),
$_ . " business days") , '%A') for (1..7);
__END__
$ perl test.pl
Friday
Monday
Tuesday
Wednesday
Thursday
Friday
Monday
Hope this helps, BR.
Seeking for Perl wisdom...on the process of learning...not there...yet!
| [reply] [d/l] [select] |
|
It seems that you spent a lot of time on your answer, but unfortunately it seems you misunderstood my question.
I simply want a list of the localized names of weekdays.
Look at the other answers if it is still unclear.
Thanks for your attempt, though.
| [reply] |
|
Hello Sec,
Sorry for the late reply, but I just noticed your reply.
Here is a sample of the same process and module by using French as everyone is providing you:?
#!/usr/bin/perl
use strict;
use warnings;
use Date::Manip;
use feature 'say';
Date_Init("Language=French");
say UnixDate(DateCalc(
ParseDate("aujourd'hui"),
$_ . " jours plus tard") , '%A') for (1..7);
__END__
$ perl test.pl
mardi
mercredi
jeudi
vendredi
samedi
dimanche
lundi
More information regarding the languages that the module can support Date::Manip::Lang.
Hope this helps, BR.
Seeking for Perl wisdom...on the process of learning...not there...yet!
| [reply] [d/l] [select] |
Re: Localized weekday names
by Anonymous Monk on Nov 02, 2017 at 17:53 UTC
|
Many time-manipulation routines such as (I think ...) Time::Piece are "part of the Core" so they should always be available. I definitely recommend replacing this existing piece of logic with equivalent logic which uses it. "Dates and Times have been done to death." You shouldn't have to write (or, keep) your own custom treatment of logic to do these universal chores. | [reply] |