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

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

Related

ksqldb iso8601 datetime format return null

Hello i have varchar column with datetime.
its utc
|2022-02-09T13:27:17.165116Z
|2022-02-09T13:27:27.3850848Z
|2022-02-09T13:28:18.5537284Z
on select query parse as by standart but return 'null' for all rows:
PARSE_TIMESTAMP(entrydate, 'yyyy-MM-ddTHH:mm:ss.SSSZZZZ')
code:
JsonSerializer.Serialize(DateTime.UtcNow);
This is because ksqldb only supports up to millisecond precision see https://www.confluent.io/blog/ksqldb-2-0-introduces-date-and-time-data-types/
There is a github issue tracking support for finer time resolution like microseconds here https://github.com/confluentinc/ksql/issues/8243
The problem is your DateFormat, yyyy-MM-ddTHH:mm:ss.SSSZZZZ which expects a precision of milliseconds but, from your input, it's microseconds.
To cover all the scenarios (as you are serializing it with JsonSerializer.Serialize, and it can happen that you don't even have anything after the seconds, or, milliseconds is zero: 2022-02-09T13:28:18Z) you would need to use the following format:
'yyyy-MM-dd''T''HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]''Z'''
This will cover all the use cases with/without the milliseconds/microseconds precision
More about the formatting:
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
So we use the following formatting options to specify that the precision is optional:
[ optional section start
] optional section end
and
S fraction-of-second fraction 978
note that you also have to 'escape' the letters:
https://docs.ksqldb.io/en/latest/developer-guide/ksqldb-reference/create-stream/#timestamp_format
Possible improvement (give it a try):
PARSE_TIMESTAMP(entrydate, 'yyyy-MM-dd''T''HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]X', 'UTC')
(you have to specify timezone so that it can parse the X to a correct timestamp including the zone)
from the Java DateTimeFormatter docs:
Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero, whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.

(Postgresql) How to convert an emoji (or emoticon) to its unicode representation

Currently I am using python to get an emojis unicode representation.
I want to be able to do this using postgresql. Example:
messageText
----------
😀
select unicodeValue(messageText) from table where messageText = '😀';
Result: 'U+1F600'
This assumes that the database encoding is UTF-8, but that is a requirement anyway if you want to represent such strange characters:
SELECT to_hex(ascii('😀'));
to_hex
--------
1f600
(1 row)

Change currency sign oracle d2k reports?

I want to replace $ sign to 'Rs.' in oracle d2k reports. In some system it is displaying Rs but in some system it is showing $. From where I have to change the sign.
You can use the currency in your NLS_TERRITORY settings as follows:
select to_char(123456789.91, 'L999,999,999,990.00') from dual;
L999,999,999,990.00 is the format mask you may be able to set in the property sheet (it's a while since I used Reports) or you can use a sql function like in the example above.
Or you can take the date and format it as a string (as above) and concatenate with the character you want to display. Obviously this isn't as flexible.
select 'Rs'||to_char(123456789.91, '999,999,999,990.00') from dual;
You can check your nls_settings by connecting in sqlplus
SELECT * FROM nls_session_parameters;
You can use this code as well.
SELECT TO_CHAR
(-10000,
'L99G999D99MI',
'NLS_NUMERIC_CHARACTERS = '',.''
NLS_CURRENCY = ''RS'' '
) "Amount"
FROM DUAL;

PowerShell date format not accepted in SQL

I'm having kind of a strange problem. When the server's Region and Language settings is set to English (United States) there are no issues with objects containing the date and time. But when I change it to my countries local Dutch (Belgium) I am experiencing problems in some of my PowerShell scripts.
Is there somewhere a variable in PowerShell that needs to be set to fix this? Or do I have to default to English date formats on the server all the time?
We use for example the SQL module provided by Don Jones for filling up an SQL database. This line generates an error when it's set to Dutch, but not when it's set to English:
if ($properties[$property] -eq 'datetime2') { [datetime]$prop = $result.GetDateTime($result.GetOrdinal($property)) }
The only thing I do to retrieve the date is Get-Date without anything special. And it generates this error when set to Dutch (Belgium):
Exception calling "ExecuteNonQuery" with "0" argument(s): "Conversion failed when converting date and/or time from char
acter string."
I've experienced the same problem when generating stuff for Excel sheets. It also complains about the date time format.
For exporting information like DateTime fields to SQL, the default language setting is English (United States).
So when your Region and Language settings are different from the default for SQL, being: English (United States) <> Dutch (Belgium), you should use the following format in your code to comply to the English defaults:
Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$_.whenCreated.ToString('yyyy-MM-dd HH:mm:ss')
Another solution is to change the default language for input in SQL Express 2014:
Right click the server instance and select Properties > Advanced
Change Default language to Dutch (or what you use)
Confirm with Ok
Still in SQL Management Studio go to Security > Logins (below Databases)
Double click your user name and select Dutch below as Default language
Restart SQL Management Studio and you should be good to go
Result:
When you use the CmdLet Get-Date in your PowerShell code it will work as designed when transferring data to SQL. The system language for SQL and Windows is still English but the formatting used is Dutch.
I use this for Datetime2 in SQL Server.
Function Get-Datetime2([datetime]$Date = $(Get-Date) ) {
$DT = Get-Date -Date $Date
[string]$DateTime2 = $DT.Month.ToString() + '/'
[string]$DateTime2 += $DT.Day.ToString() + '/'
[string]$DateTime2 += $DT.Year.ToString() + ' '
[string]$DateTime2 += $DT.TimeOfDay.ToString()
return $DateTime2
}
Get-Datetime2
returns something that looks like this.
3/12/2018 03:04:34.7496659
If you already use Don Jones' module you may already be familiar with type-extension through the *.types.ps1xml... There should be one in his module too, if I remember correctly.
When adding the following type declaration,
<Type>
<Name>System.DateTime</Name>
<Members>
<ScriptMethod>
<Name>ToString</Name>
<Script>
$(Get-Date $This -Format "yyyy-MM-dd HH:mm:ss")
</Script>
</ScriptMethod>
</Members>
</Type>
You basically override System.DateTime's ToString() method to the format needed by a standard SQL Server installation.
This way you can make sure that every time you load the SQL module dates they are being formatted the right way.

Get current locale name in 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. "").