9.8. Функции форматирования типов данных#

9.8. Функции форматирования типов данных

9.8. Функции форматирования типов данных #

Функции форматирования Tantor BE предоставляют мощный набор инструментов для преобразования различных типов данных (дата/время, целое число, число с плавающей запятой, числовое) в отформатированные строки и для преобразования отформатированных строк в конкретные типы данных. Таблица 9.26 перечисляет их. Все эти функции следуют общему соглашению о вызове: первый аргумент - это значение, которое нужно отформатировать, а второй аргумент - это шаблон, который определяет формат вывода или ввода.

Таблица 9.26. Функции форматирования

Функция

Описание

Пример(ы)

to_char ( timestamp, text ) → text

to_char ( timestamp with time zone, text ) → text

Преобразует временную метку в строку в соответствии с заданным форматом.

to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS')05:31:12

to_char ( interval, text ) → text

Преобразует интервал в строку в соответствии с заданным форматом.

to_char(interval '15h 2m 12s', 'HH24:MI:SS')15:02:12

to_char ( numeric_type, text ) → text

Преобразует число в строку в соответствии с заданным форматом; доступно для типов integer, bigint, numeric, real, double precision.

to_char(125, '999')125

to_char(125.8::real, '999D9')125.8

to_char(-125.8, '999D99S')125.80-

to_date ( text, text ) → date

Преобразует строку в дату в соответствии с заданным форматом.

to_date('05 Dec 2000', 'DD Mon YYYY')2000-12-05

to_number ( text, text ) → numeric

Преобразует строку в числовое значение в соответствии с заданным форматом.

to_number('12,454.8-', '99G999D9S')-12454.8

to_timestamp ( text, text ) → timestamp with time zone

Преобразует строку в метку времени в соответствии с заданным форматом. (См. также функцию to_timestamp(double precision) в Таблица 9.33).

to_timestamp('05 Dec 2000', 'DD Mon YYYY')2000-12-05 00:00:00-05


Подсказка

Существуют функции to_timestamp и to_date, предназначенные для обработки форматов ввода, которые не могут быть преобразованы простым приведением типов. Для большинства стандартных форматов даты/времени достаточно привести исходную строку к требуемому типу данных, что намного проще. Аналогично, функция to_number не требуется для стандартных числовых представлений.

В шаблонной строке вывода функции to_char есть определенные шаблоны, которые распознаются и заменяются на соответствующе отформатированные данные на основе заданного значения. Любой текст, который не является шаблонным образцом, просто копируется без изменений. Аналогично, в шаблонной строке ввода (для других функций) шаблонные образцы определяют значения, которые должны быть предоставлены входной строкой данных. Если в шаблонной строке есть символы, которые не являются шаблонными образцами, соответствующие символы во входной строке данных просто пропускаются (независимо от того, равны ли они символам в шаблонной строке).

Таблица 9.27 показывает доступные шаблоны для форматирования значений даты и времени.

Таблица 9.27. Шаблоны форматирования даты/времени

ШаблонОписание
HHчас дня (01–12)
HH12час дня (01–12)
HH24час дня (00–23)
MIминута (00–59)
SSсекунда (00–59)
MSмиллисекунда (000–999)
USмикросекунда (000000–999999)
FF1десятая доли секунды (0–9)
FF2сотая доли секунды (00–99)
FF3millisecond (000–999)
FF4десятая доли миллисекунды (0000–9999)
FF5сотая доли миллисекунды (00000–99999)
FF6микросекунда (000000–999999)
SSSS, SSSSSсекунды после полуночи (0–86399)
AM, am, PM или pmиндикатор полудня (без точек)
A.M., a.m., P.M. или p.m.индикатор полудня (с точками)
Y,YYYгод (4 или более цифр) с запятой
YYYYгод (4 или более цифр)
YYYпоследние 3 цифры года
YYпоследние 2 цифры года
Yпоследняя цифра года
IYYYГод недели по стандарту ISO 8601 (4 или более цифр)
IYYпоследние 3 цифры года нумерации недель ISO 8601
IYпоследние 2 цифры года нумерации недель ISO 8601
Iпоследняя цифра года недели по стандарту ISO 8601
BC, bc, AD или adиндикатор эпохи (без точек)
BC, bc, AD или adиндикатор эпохи (с точками)
MONTHполное название месяца в верхнем регистре (заполнено пробелами до 9 символов)
Monthполное название месяца с заглавной буквы (заполнено пробелами до 9 символов)
monthполное название месяца в нижнем регистре (заполнено пробелами до 9 символов)
MONсокращенное название месяца в верхнем регистре (3 символа на английском языке, локализованная длина может отличаться)
Monсокращенное название месяца с заглавной буквы (3 символа на английском языке, локализованная длина может отличаться)
monсокращенное название месяца в нижнем регистре (3 символа на английском языке, локализованная длина может отличаться)
MMномер месяца (01–12)
DAYполное название дня в верхнем регистре (заполнено пробелами до 9 символов)
Dayполное название дня с заглавной буквы (заполнено пробелами до 9 символов)
dayполное название дня в нижнем регистре (заполнено пробелами до 9 символов)
DYсокращенное название дня в верхнем регистре (3 символа на английском языке, локализованная длина может отличаться)
Dayсокращенное написание дня с заглавной буквы (3 символа на английском языке, локализованная длина может отличаться)
dyсокращенное название дня недели в нижнем регистре (3 символа на английском языке, локализованная длина может отличаться)
DDDдень года (001–366)
IDDDдень недели в году, согласно нумерации недель ISO 8601 (001–371; первый день года - понедельник первой недели ISO)
DDдень месяца (01–31)
Dдень недели, Воскресенье (1) до Суббота (7)
IDДень недели ISO 8601, понедельник (1) до воскресенья (7)
Wнеделя месяца (1–5) (первая неделя начинается в первый день месяца)
WWномер недели года (1–53) (первая неделя начинается в первый день года)
IWномер недели года по стандарту ISO 8601 (01–53; первый четверг года находится в неделе 1)
CCвек (2 цифры) (двадцать первый век начинается 2001-01-01)
JЮлианская дата (целое число дней с 24 ноября 4714 г. до н.э. в полночь местного времени; см. Раздел B.7)
Qquarter
RMмесяц в верхнем регистре римских цифр (I–XII; I=Январь)
rmмесяц в нижнем регистре римских цифр (i–xii; i=январь)
TZаббревиатура временной зоны в верхнем регистре (поддерживается только в функции to_char)
tzаббревиатура часового пояса в нижнем регистре (поддерживается только в функции to_char)
TZHчасовой пояс
TZMминуты часового пояса
OFсмещение часового пояса от UTC (поддерживается только в функции to_char)

Модификаторы могут быть применены к любому шаблону для изменения его поведения. Например, FMMonth - это шаблон Month с модификатором FM. Таблица 9.28 показывает модификаторы для форматирования даты/времени.

Таблица 9.28. Модификаторы шаблона для форматирования даты/времени

МодификаторОписаниеПример
FM префиксрежим заполнения (подавление ведущих нулей и заполнительных пробелов)FMMonth
TH суффикссуффикс верхнего регистра порядкового числаDDTH, например, 12TH
th суффикссуффикс порядкового числа в нижнем регистреDDth, например, 12th
FX префиксфиксированный формат глобальной опции (см. примечания по использованию)FX Month DD Day
TM префиксрежим перевода (использовать локализованные названия дней и месяцев на основе lc_time)TMMonth
SP суффиксрежим проверки орфографии (не реализован)DDSP

Примечания по использованию форматирования даты/времени:

  • FM подавляет ведущие нули и конечные пробелы, которые в противном случае добавляются для создания фиксированной ширины вывода шаблона. В Tantor BE, FM изменяет только следующую спецификацию, в то время как в Oracle FM влияет на все последующие спецификации, и повторяющиеся модификаторы FM переключают режим заполнения вкл./выкл.

  • TM подавляет конечные пробелы, независимо от того, указан ли FM.

  • to_timestamp и to_date игнорируйте регистр букв во входных данных; так, например, MON, Mon, и mon принимают одинаковые строки. При использовании модификатора TM регистр букв приводится к нижнему регистру в соответствии с правилами сортировки входных данных функции (см. Раздел 22.2).

  • to_timestamp и to_date пропускайте несколько пробелов в начале входной строки и вокруг значений даты и времени, если не используется опция FX. Например, to_timestamp(' 2000    JUN', 'YYYY MON') и to_timestamp('2000 - JUN', 'YYYY-MON') работают, но to_timestamp('2000    JUN', 'FXYYYY MON') возвращает ошибку, потому что to_timestamp ожидает только один пробел. FX должно быть указано первым элементом в шаблоне.

  • В разделителе (пробеле или символе, не являющемся буквой или цифрой) в строке шаблона функций to_timestamp и to_date совпадает с любым одиночным разделителем во входной строке или пропускается, если не используется опция FX. Например, to_timestamp('2000JUN', 'YYYY///MON') и to_timestamp('2000/JUN', 'YYYY MON') работают, но to_timestamp('2000//JUN', 'YYYY/MON') вызывает ошибку, потому что количество разделителей во входной строке превышает количество разделителей в шаблоне.

    Если указано FX, разделитель в строке шаблона соответствует ровно одному символу во входной строке. Однако следует отметить, что символ входной строки не обязательно должен быть таким же, как разделитель в строке шаблона. Например, to_timestamp('2000/JUN', 'FXYYYY MON') работает, но to_timestamp('2000/JUN', 'FXYYYY  MON') возвращает ошибку, потому что второй пробел в строке шаблона потребляет букву J из входной строки.

  • A TZH шаблонный образец может соответствовать знаковому числу. Без опции FX, минусы могут быть неоднозначными и могут быть интерпретированы как разделитель. Эта неоднозначность разрешается следующим образом: если количество разделителей перед TZH в строке шаблона меньше количества разделителей перед минусом во входной строке, минус будет интерпретирован как часть TZH. В противном случае минус будет считаться разделителем между значениями. Например, to_timestamp('2000 -10', 'YYYY TZH') соответствует -10 TZH, но to_timestamp('2000 -10', 'YYYY  TZH') соответствует 10 TZH.

  • В шаблонах функции to_char допускается использование обычного текста, который будет выведен буквально. Вы можете поместить подстроку в двойные кавычки, чтобы заставить ее интерпретироваться как буквальный текст, даже если она содержит шаблонные образцы. Например, в '"Hello Year "YYYY' символы YYYY будут заменены данными о годе, но один символ Y в слове Year не будет заменен. В функциях to_date, to_number и to_timestamp буквальный текст и текст, заключенный в двойные кавычки, приводят к пропуску количества символов, содержащихся в строке; например, "XX" пропускает два входных символа (независимо от того, являются ли они XX или нет).

    Подсказка

    До версии PostgreSQL 12 была возможность пропускать произвольный текст во входной строке с использованием символов, не являющихся буквами или цифрами. Например, to_timestamp('2000y6m1d', 'yyyy-MM-DD') раньше работало. Теперь вы можете использовать только буквенные символы для этой цели. Например, to_timestamp('2000y6m1d', 'yyyytMMtDDt') и to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') пропускают y, m и d.

  • Если нужно иметь двойные кавычки в выводе, вы должны предварить их обратной косой чертой, например '\"YYYY Month\"'. Обратные косые черты вне двойных кавычек не имеют особого значения. Внутри двойных кавычек обратная косая черта воспринимается буквально, независимо от его значения (но это не имеет особого эффекта, если следующий символ - это двойная кавычка или еще одна обратная косая черта).

  • В функциях to_timestamp и to_date, если формат года указан с меньшим количеством цифр, например, YYY, и предоставленный год содержит меньше четырех цифр, год будет скорректирован, чтобы быть ближайшим к году 2020, например, 95 станет 1995.

  • В функциях to_timestamp и to_date отрицательные годы рассматриваются как обозначение до нашей эры (BC). Если вы указываете отрицательный год и явное поле BC, то получаете снова год нашей эры (AD). Ввод года нуль рассматривается как 1 год до нашей эры (BC).

  • В to_timestamp и to_date, преобразование YYYY имеет ограничение при обработке лет с более чем 4 цифрами. Вы должны использовать какой-либо нецифровой символ или шаблон после YYYY, иначе год всегда интерпретируется как 4-значный. Например (с годом 20000): to_date('200001130', 'YYYYMMDD') будет интерпретироваться как 4-значный год; вместо этого используйте нецифровой разделитель после года, например to_date('20000-1130', 'YYYY-MMDD') или to_date('20000Nov30', 'YYYYMonDD').

  • В функциях to_timestamp и to_date поле CC (век) принимается, но игнорируется, если присутствует поле YYY, YYYY или Y,YYY. Если CC используется с YY или Y, то результатом будет год в указанном веке. Если указан век, но не указан год, то предполагается первый год века.

  • В функциях to_timestamp и to_date принимаются имена или номера дней недели (DAY, D и связанные типы полей), но они игнорируются при вычислении результата. То же самое относится к кварталам (Q).

  • В функциях to_timestamp и to_date можно указать дату с номером недели в соответствии с ISO 8601 (в отличие от григорианской даты) двумя способами:

    • Год, номер недели и день недели: например, to_date('2006-42-4', 'IYYY-IW-ID') возвращает дату 2006-10-19. Если вы опустите день недели, предполагается, что это 1 (понедельник).

    • Год и день года: например, to_date('2006-291', 'IYYY-IDDD') также возвращает 2006-10-19.

    Попытка ввода даты, используя смесь полей недели, нумерации по стандарту ISO 8601 и полей даты по григорианскому календарю, является бессмысленной и вызовет ошибку. В контексте года, нумеруемого по стандарту ISO 8601, понятие "месяц" или "день месяца" не имеет смысла. В контексте григорианского года, неделя по стандарту ISO не имеет смысла.

    Предостережение

    В то время как функция to_date отклонит смесь григорианской и ISO недельной нумерации даты, функция to_char этого не сделает, так как формат вывода спецификации, такие как YYYY-MM-DD (IYYY-IDDD), могут быть полезными. Но избегайте написания чего-то вроде IYYY-MM-DD; это приведет к неожиданным результатам в начале года. (См. Раздел 9.9.1 для получения дополнительной информации).

  • В функции to_timestamp, миллисекунды (MS) или микросекунды (US) используются в качестве десятичных долей секунд. Например, to_timestamp('12.3', 'SS.MS') не означает 3 миллисекунды, а 300, потому что преобразование интерпретирует это как 12 + 0.3 секунды. Таким образом, для формата SS.MS значения ввода 12.3, 12.30 и 12.300 указывают на одно и то же количество миллисекунд. Чтобы получить три миллисекунды, нужно написать 12.003, что преобразование интерпретирует как 12 + 0.003 = 12.003 секунды.

    Вот более сложный пример: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') составляет 15 часов, 12 минут, 2 секунды + 20 миллисекунд + 1230 микросекунд = 2.021230 секунды.

  • to_char(..., 'ID') номер дня недели соответствует функции extract(isodow from ...), но номер дня недели функции to_char(..., 'D') не соответствует номеру дня функции extract(dow from ...).

  • to_char(interval) форматирует HH и HH12 как показано на 12-часовых часах, например, ноль часов и 36 часов оба выводятся как 12, в то время как HH24 выводит полное значение часа, которое может превышать 23 в значении interval.

Таблица 9.29 показывает доступные шаблоны для форматирования числовых значений.

Таблица 9.29. Шаблоны форматирования чисел

ШаблонОписание
9позиция цифры (можно опустить, если незначительна)
0позиция цифры (не будет удалена, даже если незначительна)
. (точка)десятичная точка
, (запятая)разделитель групп (тысяч)
PRотрицательное значение в угловых скобках
Sзнак привязан к числу (использует локаль)
Lсимвол валюты (использует локаль)
Dдесятичная точка (использует локальные настройки)
Gразделитель группы (использует локаль)
MIминусовой знак в указанной позиции (если число < 0)
PLзнак плюс на указанной позиции (если число > 0)
SGзнак плюс/минус в указанной позиции
RNРимское число (вводится от 1 до 3999)
TH или thсуффикс порядкового числа
Vсдвигает указанное количество цифр (см. примечания)
EEEEпоказатель для научной нотации

Примечания по использованию числового форматирования:

  • 0 указывает позицию цифры, которая всегда будет печататься, даже если она содержит ведущий/заключительный ноль. 9 также указывает позицию цифры, но если это ведущий ноль, то он будет заменен пробелом, а если это заключительный ноль и задан режим заполнения, то он будет удален. (Для to_number() эти два символа шаблона эквивалентны).

  • Если формат предоставляет меньше дробных цифр, чем число, которое форматируется, to_char() округлит число до указанного количества дробных цифр.

  • Символы шаблона S, L, D и G представляют знак, символ валюты, десятичную точку и разделитель тысяч, определенные текущей локалью (см. lc_monetary и lc_numeric). Символы шаблона точка и запятая представляют собой точно эти символы с значениями десятичной точки и разделителя тысяч, независимо от локали.

  • Если в шаблоне функции to_char() не указано явное положение знака, то одна колонка будет зарезервирована для знака и он будет привязан к числу (появится слева от числа). Если S находится слева от некоторых 9, то он также будет привязан к числу.

  • Знак, отформатированный с использованием SG, PL или MI, не привязан к числу; например, to_char(-12, 'MI9999') выводит '-  12', а to_char(-12, 'S9999') выводит '  -12'. (В реализации Oracle не разрешается использование MI перед 9, а требуется, чтобы 9 предшествовал MI).

  • TH не преобразует значения меньше нуля и не преобразует дробные числа.

  • PL, SG и TH - это расширения Tantor BE.

  • В функции to_number, если используются шаблоны, не являющиеся данными, такие как L или TH, соответствующее количество входных символов пропускается, независимо от того, соответствуют ли они шаблону, если они не являются данными символами (то есть цифры, знак, десятичная точка или запятая). Например, TH пропустит два символа, не являющихся данными.

  • V с to_char умножает входные значения на 10^n, где n - количество цифр после V. V с to_number делит аналогичным образом. to_char и to_number не поддерживают использование V в сочетании с десятичной точкой (например, 99.9V99 не разрешено).

  • EEEE (научная нотация) не может использоваться в сочетании с любыми другими шаблонами или модификаторами форматирования, кроме шаблонов для цифр и десятичной точки, и должна находиться в конце строки формата (например, 9.99EEEE является допустимым шаблоном).

Некоторые модификаторы могут быть применены к любому шаблону для изменения его поведения. Например, FM99.99 - это шаблон 99.99 с модификатором FM. Таблица 9.30 показывает модификаторы для числового форматирования.

Таблица 9.30. Шаблонные модификаторы для числового форматирования

МодификаторОписаниеПример
FM префиксрежим заполнения (подавление конечных нулей и заполнительных пробелов)FM99.99
TH суффикссуффикс верхнего регистра порядкового числа999TH
th суффикссуффикс порядкового числа в нижнем регистре999th

Таблица 9.31 показывает некоторые примеры использования функции to_char.

Таблица 9.31. to_char Примеры

ВыражениеРезультат
to_char(current_timestamp, 'День, DD  HH12:MI:SS')'Вторник  , 06  05:39:18'
to_char(current_timestamp, 'FMDay, FMDD  HH12:MI:SS')'Вторник, 6  05:39:18'
to_char(-0.1, '99.99')'  -.10'
to_char(-0.1, 'FM9.99')'-.1'
to_char(-0.1, 'FM90.99')'-0.1'
to_char(0.1, '0.9')' 0.1'
to_char(12, '9990999.9')'    0012.0'
to_char(12, 'FM9990999.9')'0012.'
to_char(485, '999')' 485'
to_char(-485, '999')'-485'
to_char(485, '9 9 9')' 4 8 5'
to_char(1485, '9,999')' 1,485'
to_char(1485, '9G999')' 1 485'
to_char(148.5, '999.999')' 148.500'
to_char(148.5, 'FM999.999')'148.5'
to_char(148.5, 'FM999.990')'148.500'
to_char(148.5, '999D999')' 148,500'
to_char(3148.5, '9G999D999')' 3 148,500'
to_char(-485, '999S')'485-'
to_char(-485, '999MI')'485-'
to_char(485, '999MI')'485 '
to_char(485, 'FM999MI')'485'
to_char(485, 'PL999')'+485'
to_char(485, 'SG999')'+485'
to_char(-485, 'SG999')'-485'
to_char(-485, '9SG99')'4-85'
to_char(-485, '999PR')'<485>'
to_char(485, 'L999')'DM 485'
to_char(485, 'RN')'        CDLXXXV'
to_char(485, 'FMRN')'CDLXXXV'
to_char(5.2, 'FMRN')'V'
to_char(482, '999th')' 482nd'
to_char(485, '"Good number:"999')'Good number: 485'
to_char(485.8, '"Pre:"999" Post:" .999')'Pre: 485 Post: .800'
to_char(12, '99V999')' 12000'
to_char(12.4, '99V999')' 12400'
to_char(12.45, '99V9')' 125'
to_char(0.0004859, '9.99EEEE')' 4.86e-04'