Oracle TO_DATE不保留格式

时间:2010-01-07 21:38:16

标签: oracle

由于这似乎是一个语法问题,我的搜索没有产生任何有用的结果。

我正在尝试使用GMT时间进行从美国数据库获取欧洲数据的查询。我需要获得欧洲时间,但似乎无法让它正常工作。

让我们说“myDateField”= '01 -01-2010'

SELECT TO_CHAR(myDateField + (60 / 1440), 'Mon" "DD", "YYYY')

产生我想要的东西,但我需要它作为约会 产生:' 2010年1月1日'

SELECT TO_DATE(TO_CHAR(myDateField + (60 / 1440)), 'Mon" "DD", "YYYY')

出现“非有效月份”错误 产生:错误

SELECT TO_DATE(TO_CHAR(myDateField + (60 / 1440), 'Mon" "DD", "YYYY'), 'Mon" "DD", "YYYY')

正常工作,但格式化已丢失 产生:' 01-01-2010 '

我如何格式化这个以便我可以获得第一个语句给出的结果,还可以将其保留为日期?或者是否有更好的方法?

修改
就像在不同情况下工作的这个特定查询的一个例子......这是相同的查询,但它不是转换到欧洲时间,而是转换到北美的另一个时区。

SELECT TO_DATE(TO_CHAR(NEW_TIME(myDateField, 'GMT', 'MDT')), 'Mon" "DD", "YYYY')

将数据保存为日期,同时生成我想要的内容 产生:' 2010年1月1日'

总结:

有没有办法取“myDateField +(60/1440)”,或使用“FROM_TZ”关键字,并使结果使用“Mon”“DD”,“YYYY”格式,同时保留它的日期类型?

3 个答案:

答案 0 :(得分:4)

我认为重要的是要意识到您希望的格式在从DATE转换为CHAR类型时生效。所以你的要求“设置格式但保留日期”没有意义 - 不是在甲骨文中它没有。

如果您只想为某个日期添加一些时间间隔,并将其保留为日期,则只需以下所示:

myDateCol + (60 / 1440) -- add one hour to the date

如果你想格式化欧洲风格,那就变成了

TO_CHAR(myDateCol + (60 / 1440), 'MON DD, YYYY')

但当然,它将是字符串,是人类可读的实际日期值表示。而且由于格式的原因,这实际上缺乏时间信息。

您当然可以将其转换回日期:

TO_DATE(TO_CHAR(myDateCol + (60 / 1440), 'MON DD, YYYY'), 'MON DD, YYYY')

但严重 - 没有意义 - 因为字符串中没有时间部分,这个日期实际上将是00:00:00作为时间。所以你只是丢失了信息。

当你做这样的事情时,这就变得清晰了:

TO_CHAR(myDateCol + (60 / 1440), 'MON DD, YYYY HH24:MI:SS')

也比较一下:

TO_CHAR(
  TO_DATE(
    TO_CHAR(myDateCol + (60 / 1440), 'MON DD, YYYY HH24:MI:SS')
  , 'MON DD, YYYY'
  )
, 'MON DD, YYYY HH24:MI:SS'
)

(最后一次演绎演示了你如何截断时间)

答案 1 :(得分:3)

日期只是一个日期 - 它没有固有的字符串格式。它具有默认格式,也就是说,当您将某个日期查询到某个程序或库中并将其作为字符串提取时,会有一个默认格式来设置格式。

一种方法是简单地查询日期并让客户端程序对其进行格式化。例如,在Java中,您可以使用DateFormat类。

但您也可以尝试ALTER SESSION SET NLS_DATE_FORMAT = 'Mon dd, yyyy'

这可能有用。

编辑:您的第二个查询为我返回了not a valid month错误。在按照我的ALTER SESSION建议后,您是否已经执行了此操作?

答案 2 :(得分:2)

新答案,因为第一个解决了日期与char之间的混淆,而不是时区。

你问是否有更好的方法。我认为有:使用oracle时区支持。

请参阅:http://download.oracle.com/docs/cd/B19306_01/server.102/b14225/ch4datetime.htm#i1006333

将日期时间转换为另一个时区的示例查询:

SELECT FROM_TZ(
         CAST(TO_DATE('1999-12-01 11:00:00','YYYY-MM-DD HH:MI:SS') AS TIMESTAMP)
       , 'America/New_York'
       )
       AT TIME ZONE 'America/Los_Angeles' "West Coast Time"
FROM DUAL;

使用这些功能可确保数学运算正确。之后,您当然可以按照您希望的方式对其进行格式化,例如:

SELECT TO_CHAR(
         FROM_TZ(
           CAST(TO_DATE('1999-12-01 11:00:00','YYYY-MM-DD HH:MI:SS') AS TIMESTAMP)
         , 'America/New_York'
         )
         AT TIME ZONE 'America/Los_Angeles' 
       , 'MON DD, YYYY') "West Coast Time"
FROM DUAL;

...但正如我在第一个答案中指出的那样,这里的结果将是CHAR,而不是日期。