Get current locale name in perl - perl

I want to use thousands_sep in Perl. I can get it using the following code
use strict;
use POSIX qw(setlocale locale_h LC_ALL);
setlocale(LC_ALL, "fr_FR");
my $lc=localeconv();
print $lc->{thousands_sep};
After that I would like to change locale back to previous value, but I don't know how to get locale before I used setlocale. Should I parse it from $ENV{LANG} which is set to
en_US.UTF-8 ? Or is there any other method to get locale name?

setlocale() returns the current locale when called without a second argument, eg.
my $oldlocale = setlocale(LC_ALL);
If you want to set locale according to the current environment, call it with an empty string (ie. "").

Related

How to print unicode to console in Eiffel?

Evidently in python:
print u'\u0420\u043e\u0441\u0441\u0438\u044f'
outputs:
Россия
How do I do this in Eiffel?
An example at the first page of eiffel.org (at the time of writintg) suggests the following code:
io.put_string_32 ("[
Hello!
¡Hola!
Bonjour!
こんにちは!
Здравствуйте!
Γειά σου!
]")
It is supported since EiffelStudio 20.05. (I tested the example with EiffelStudio 22.05.)
In this particular case, using print instead of io.put_string_32 works as well. However, in some boundary cases, when all character codes in the string are below 256, you may need to specify the string type explicitly:
print ({STRING_32} "Zürich") -- All character code points are below 256.
Of course, you can write the character code points explicitly:
io.put_string_32 ("%/0x041f/%/0x0440/%/0x0438/%/0x0432/%/0x0435/%/0x0442/%/0x0021/")
The output code page defaults to UTF-8 for text files and the current console code page for CONSOLE (the standard object type of io). If needed, the default encoding can be changed to any other encoding:
io.standard_default.set_encoding ({SYSTEM_ENCODINGS}.console_encoding)
On my linux OS, this code print exactly what you want:
make
-- Initialisation of `Current'
local
l_utf_converter:UTF_CONVERTER
l_string:STRING_32
do
create l_string.make_empty
l_string.append_code (0x420)
l_string.append_code (0x43e)
l_string.append_code (0x441)
l_string.append_code (0x441)
l_string.append_code (0x438)
l_string.append_code (0x44f)
print(l_utf_converter.utf_32_string_to_utf_8_string_8 (l_string))
end
In a nutshell, STRING_32 use UTF-32 and the linux console use UTF-8. The UTF_CONVERTER class can be use to convert UTF-32 to UTF-8.
I do not know if it is possible on a Windows console.

How do I use a different locale in PostgreSQL with to_char?

I know I can use use `to_char() to format currency in my default locale:
SELECT to_char(12345.67,'FML999G999G999D00');
In Australia, I get $12,345.67.
In Microsoft SQL, the format() function has an optional additional parameter for what they call the culture (together with a convenient 'c' format code for currency), so I can change the currency format.
Is there a way of changing the locale for a currency format?
The only way I know is to change lc_monetary:
lc_monetary (string)
Sets the locale to use for formatting monetary amounts, for example with the to_char family of functions. Acceptable values are system-dependent; see Section 24.1 for more information. If this variable is set to the empty string (which is the default) then the value is inherited from the execution environment of the server in a system-dependent way.
show lc_monetary ;
lc_monetary
-------------
en_US.UTF-8
SELECT to_char(12345.67,'FML999G999G999D00');
to_char
------------
$12,345.67
set lc_monetary = 'en_GB.UTF-8';
SELECT to_char(12345.67,'FML999G999G999D00');
to_char
------------
£12,345.67

In RPG, use a date, in *job format from a file

I'm trying to convert, in a RPG program, a date from a file (it's from the DSPJRN command, so the field si 6 numeric, in JOB format).
I want to use it as a date in my program, but I can't achieve it correctly.
I have tried to describe a field with type "D": date, keyword datfmt(*job) to convert the value from the file, but datfmt(*job) is incorrect (error RNF0612)
I have tried to retrieve the job Date format from a CLP program with RTVJOBA DATFMT(&FMT), and use the variable in RPG to convert the date like this
eval ztJODATE = %date(JODATE:FMT)
but it doesn't compile : error RNF0606 . I think that I can't use a variable for the format in the %date built-in function.
Is this a way to do what I want, or am I forced to transform the date value in SQL before using its value in RPG?
PS: I don't want to hardcode the format in my RPG program!
You can specify *JOBRUN for %DATE.
eval ztJODATE = %date(JODATE:*JOBRUN)
Note that RPG retrieves the job date format during initialization of the module, so if you change the job date format while the program is running, RPG will not understand the date.
Rather than using DSPJRN to an outfile, the recommended way to retrieve and process journal entries would be to use one of the programatic interfaces provided by IBM i.
Retrieve Journal Entries (QjoRetrieveJournalEntries) API
QSYS2.DISPLAY_JOURNAL() stored procedure
You could also use a *TYPE3 or higher format for the output file. Rather than the separate job formatted data & time fields, there's a single char(26) system timestamp field.
Having said that, there is a Convert Date and Time Format (QWCCVTDT) API that accepts '*JOB' as an input format specifier..

Why is Powershell Write-Output Date Format not the System Setting?

We have a Windows Server with the Region settings for short dates set to dd.MM.yyyy. However powershell outputs the dates as MM/dd/yyyy:
$d = (Get-Item .\somefile.txt).CreationTime
Write-Output "$d" # => 09/26/2016 15:35:35
Also, the toString() function returns a different (correct) format
Write-Output "$($d.toString())" # => 26.09.2016 15:35:35
Questions:
Why does powershell use MM/dd/yyyy?
Why are the 2 formats above different?
I know we can set the format in our powershell profile but is there no "System" setting which determines it?
Scripts are often used for automation, rarely for interaction with users or creating UIs. The automatic conversion to string that happens when you put a variable inside a string, e.g. "$d" will always use the invariant culture and never the user's preference. Same goes for numbers, for example. This is precisely to avoid issues that arise where a string would contain a different format for a different user or on a different machine.
If you need control over the format, convert to string explicitly, not implicitly.
The same holds for parsing, incidentally. You can cast a string to a datetime, or number, but this requires a certain format to work. If you want to use the user's preference, then use [DateTime]::Parse instead.

Determining Local Time in another Timezone

How can I determine the current date and time of various countries using a PERL script that executes on a server in the US? For example, getDTnow() should determine the current date and time on the server and use that to return the date and time of various countries.
P.S: It would be great if this can be done using only the built-in functions, without any external modules.
Conclusion: Date maths is [use swear word here] complicated and easy to get wrong. Other perl gurus on IRC, groups and other parts of the net confirmed what Ether had been advicing me - use DateTime. DVK's solution is also pretty neat for those of you who don't mind messing with the perl environment. (Note: Though on windows, the caveats section of the Time::Piece docs says one should be careful while 'Setting $ENV{TZ} in Threads on Win32').
DateTime is a wonderful library that can use standard timezones to do everything you desire and more:
use DateTime;
# returns local time in Italy
my $dt = DateTime->now(time_zone => 'Europe/Rome');
# prints time in desired format
print "The current date and time in Italy is: ", $dt->strftime('%Y-%m-%d %T');
You can control which timezone localtime returns in via TZ environmental variable:
local $ENV{TZ} = ":/usr/share/lib/zoneinfo/Asia/Tokyo";
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime();
print "$sec,$min,$hour,$mday,$mon,$year,$wday,$yday\n"'
# Prints 40,58,4,12,0,111,3,11
local $ENV{TZ} = ":/usr/share/lib/zoneinfo/Europe/London";
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime();
print "$sec,$min,$hour,$mday,$mon,$year,$wday,$yday\n"'
# Prints 41,58,19,11,0,111,2,10
Unfortunately, the path above is different on different Unixes (/usr/share/lib/zoneinfo on Solaris, /usr/share/zoneinfo on Linux). Since there appear to be no other variations, a slightly portable version would check which of the 2 directories exists and use that - but this obviously only works on Solaris and Linux and may be other unixes. No idea about Windows/MacOS/whatnot.
Valid locations for TZ can be found here: http://www.timezoneconverter.com/cgi-bin/tzref.tzc (but not all of them would necessarily be available on your system - check the above directory).
Please see http://en.wikipedia.org/wiki/Tz_database for more info on TZ database.
You could always store the variation from your timezone in a hash where the key is the timezone and the value is the adjustment from the current time. then when you pass the current time it should return the local time for that zone.