英文:
Oracle Format Date without Converting it to CHAR
问题
我想在Oracle中格式化日期而不转换为char,例如to_char(date,'dd/mm/yyyy')
,我尝试使用to_date
:
to_date(papf.start_date,'yyyy-mm-dd')
但它实际上并不进行格式化,另外我想要的格式是mm/dd/yyyy
,我该如何做?
英文:
I Want to Format Date in Oracle without Converting to char e.g. to_char(date,'dd/mm/yyyy'
), I tried using to_date
:
to_date(papf.start_date,'yyyy-mm-dd')
But it doesn't really format anything, in addition I want the format to be mm/dd/yyyy
, how can I do that?
答案1
得分: 3
DATE
是一种二进制数据类型,由7个字节组成,表示世纪、年份、月份、日期、小时、分钟和秒。它始终包括这7个组件,永远不以任何特定的人类可读格式存储。
问题是:
> 我想在 Oracle 中格式化日期,而不将其转换为字符
这并没有意义,因为日期是以二进制数据形式存储的。这就像要查看 MP3 文件的字节而不将其转换为声音,或查看 JPEG 文件而不将字节解码为像素和颜色。
如果您希望将日期以特定格式呈现,那么您需要将其转换为非二进制格式,这将是一串字符。
您可以选择:
-
使用
TO_CHAR
明确将日期转换为字符串:SELECT TO_CHAR(papf.start_date,'yyyy-mm-dd') FROM your_table papf
-
允许您正在使用的数据库客户端应用程序在向您显示日期时将其隐式格式化为字符串。如果您使用 SQL*Plus 或 SQL Developer,则它们将使用
NLS_DATE_FORMAT
会话参数作为日期和字符串之间隐式转换的默认格式模型,您可以使用以下命令设置它:ALTER SESSION SET NLS_DATE_FORMAT = 'yyyy-mm-dd';
然后以日期值的形式选择它,让客户端格式化它:
SELECT papf.start_date FROM your_table papf
如果您使用不同的客户端应用程序,则需要查看其文档,了解它如何格式化日期。
-
如果您真的不想将其作为字符串,则可以使用:
SELECT TO_NUMBER(TO_CHAR(papf.start_date, 'DDMMYYYY')) FROM your_table papf
或
SELECT 1000000 * EXTRACT(DAY FROM papf.start_date) + 10000 * EXTRACT(MONTH FROM papf.start_date) + 1 * EXTRACT(YEAR FROM papf.start_date) FROM your_table papf
这两者都会将其显示为一个8位数字(但不会以斜杠的方式显示,不符合您的期望格式)。
> 我尝试使用 to_date:
>
> lang-sql > to_date(papf.start_date,'yyyy-mm-dd') >
>
> 但它实际上没有格式化任何内容
它没有格式化任何内容,因为DATE
是一种二进制数据类型,从不存储任何特定(人类可读)格式。
此外,它可能会导致日期出现问题,因为TO_DATE
的第一个参数是一个字符串,所以您实际上是执行了隐式的日期到字符串转换,然后再将其转换回日期,因此查询实际上与以下查询相同:
to_date(
TO_CHAR(
papf.start_date,
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
),
'yyyy-mm-dd'
)
所以,如果您执行以下操作:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-RR';
SELECT TO_CHAR(
SYSDATE,
'yyyy-mm-dd hh24:mi:ss'
) AS today,
TO_CHAR(
to_date(SYSDATE,'yyyy-mm-dd'),
'yyyy-mm-dd hh24:mi:ss'
) AS today_with_to_date
FROM DUAL;
然后输出为:
TODAY | TODAY_WITH_TO_DATE |
---|---|
2023-03-20 18:42:40 | 0020-03-23 00:00:00 |
在这种情况下,使用 TO_DATE
导致了年份和日期的交换,并将时间截断为午夜。
永远不要在已经是日期值的情况下使用 TO_DATE
。
英文:
A DATE
is a binary data type consisting of 7 bytes representing century, year-of-century, month, day, hour, minute and second. It ALWAYS has those 7 components and it is NEVER stored in any particular human-readable format.
Asking:
> I Want to Format Date in Oracle without Converting to char
Does not make sense given that a date is stored as binary data. It is like asking to look at the bytes of an MP3 file without converting it to sound or to look at a JPEG file without decoding the bytes to pixels and colours.
If you want to have a date in a particular format then you need to convert it to a non-binary format and that would be a string of characters.
You can either:
-
Explicitly convert a date to a string using
TO_CHAR
:SELECT TO_CHAR(papf.start_date,'yyyy-mm-dd') FROM your_table papf
-
Allow whatever client application you are using to access the database to implicitly format the date as a string when it displays it to you. If you are using SQL*Plus or SQL Developer then they will use the
NLS_DATE_FORMAT
session parameter as the default format model for implicitly converting between dates and strings and you can set that using:ALTER SESSION SET NLS_DATE_FORMAT = 'yyyy-mm-dd';
Then select the value as a date and allow the client to format it:
SELECT papf.start_date FROM your_table papf
If you are using a different client application then you will need to look at its documentation and find out how it formats dates.
-
If you really don't want it as a string then you can use:
SELECT TO_NUMBER(TO_CHAR(papf.start_date, 'DDMMYYYY')) FROM your_table papf
or
SELECT 1000000 * EXTRACT(DAY FROM papf.start_date) + 10000 * EXTRACT(MONTH FROM papf.start_date) + 1 * EXTRACT(YEAR FROM papf.start_date) FROM your_table papf
Which both display it as an 8-digit number (but won't be in your desired format with the slashes).
> I tried using to_date:
>
> lang-sql
> to_date(papf.start_date,'yyyy-mm-dd')
>
>
> But it doesn't really format anything
It doesn't format anything because a DATE
is a binary data-type and never stores any particular (human-readable) format.
Additionally, it can cause issues with the date as TO_DATE
takes a string as the first argument so you are effectively performing an implicit date-to-string conversion and then converting it back to a date so the query is effectively the same as:
to_date(
TO_CHAR(
papf.start_date,
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
),
'yyyy-mm-dd'
)
So, if you do:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-RR';
SELECT TO_CHAR(
SYSDATE,
'yyyy-mm-dd hh24:mi:ss'
) AS today,
TO_CHAR(
to_date(SYSDATE,'yyyy-mm-dd'),
'yyyy-mm-dd hh24:mi:ss'
) AS today_with_to_date
FROM DUAL;
Then it outputs:
TODAY | TODAY_WITH_TO_DATE |
---|---|
2023-03-20 18:42:40 | 0020-03-23 00:00:00 |
In this case, using TO_DATE
has swapped the year and day over and has truncated the time back to midnight.
NEVER use TO_DATE
on a value that is already a date.
答案2
得分: 1
如果您不想指定文字日期格式(实际上这是推荐的做法),您可以设置所有日期转换为字符串的默认值:
alter session set nls_date_format='mm/dd/yyyy';
select start_date from ...
然而,尽管这在sqlplus和任何将一切转换为字符串的其他客户端中都有效,但如果您的客户端实际上需要日期,将不会进行任何转换,而您也不希望进行转换。在将日期显示给人类或在报告上的最终阶段之前,请使用日期作为实际日期进行操作,而不是字符串。如果您使用某种数据库浏览或报告工具,很可能它在某个地方有一个选项部分,您可以在那里自动设置默认的NLS日期格式。
英文:
If you don't want to specify a literal date format (which is in fact recommended practice), you can set the default for all date-to-string conversions:
alter session set nls_date_format='mm/dd/yyyy';
select start_date from ...
However, while this will work in sqlplus and any other client that converts everything to a string, should your client be actually wanting a date, no conversion will take place, and you wouldn't want it to. Work with dates as actual dates, not strings, until you get to the final point of displaying it to a human or on a report. If you are using a database browsing or reporting tool of some kind, it is likely that it has an Options section somewhere where you can set the default NLS date format automatically.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论