ITPUB论坛-中国最专业的IT技术社区

 找回密码
 注册
查看: 493|回复: 5

[每日一题] PL/SQL Challenge 每日一题:2018-1-4 TO_TIMESTAMP_TZ函数

[复制链接]
论坛徽章:
486
秀才
日期:2015-09-09 10:33:01秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21
发表于 2018-1-9 06:03 | 显示全部楼层 |阅读模式

最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

每两周的优胜者可获得itpub奖励的技术图书一本。

以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808

原始出处:
http://www.plsqlchallenge.com/

作者: Kim Berg Hansen

运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品

我有些朋友住在不同的时区:

create table qz_friends (
   friend   varchar2(10)
, tzname   varchar2(64)
)
/

insert into qz_friends values ('Cecilia' , 'America/Chicago')
/
insert into qz_friends values ('Lucille' , 'Europe/London'  )
/
insert into qz_friends values ('Patricia', 'Australia/Perth')
/
commit
/

在应用中,所有的会话都使用UTC时区:

alter session set time_zone='UTC'
/

我住在丹麦,时区是 Europe/Copenhagen, 我想要知道在什么时间(我的当地时间)需要给我的每个朋友发送“新年快乐”的短信,使得他们会在当地时间的午夜收到这条短信。

我写了个未完成的查询来获取这些时间:

select friend
     , to_char(
          ##REPLACE##
        , 'YYYY-MM-DD HH24:MI:SS TZR'
       ) as time_for_sms
  from qz_friends
order by time_for_sms
/

哪些选项包含的表达式可用来取代##REPLACE##使得查询返回这个输出:

FRIEND     TIME_FOR_SMS
---------- ----------------------------------------------------
Patricia   2017-12-31 17:00:00 EUROPE/COPENHAGEN
Lucille    2018-01-01 01:00:00 EUROPE/COPENHAGEN
Cecilia    2018-01-01 07:00:00 EUROPE/COPENHAGEN

(A)
  TO_TIMESTAMP(
             '2018-01-01 00:00:00 ' || tzname
           , 'YYYY-MM-DD HH24:MI:SS TZR'
          ) AT TIME ZONE 'Europe/Copenhagen'

(B)
TO_TIMESTAMP_TZ(
             '2018-01-01 00:00:00 ' || tzname
           , 'YYYY-MM-DD HH24:MI:SS TZR'
          ) AT TIME ZONE 'Europe/Copenhagen'

(C)
  FROM_TZ(
             TO_TIMESTAMP(
                '2018-01-01 00:00:00'
              , 'YYYY-MM-DD HH24:MI:SS'
             )
           , tzname
          ) AT TIME ZONE 'Europe/Copenhagen'

(D)
       FROM_TZ(
             TIMESTAMP '2018-01-01 00:00:00'
           , tzname
          ) AT TIME ZONE 'Europe/Copenhagen'

(E)
         ( TIMESTAMP '2018-01-01 00:00:00'
            AT TIME ZONE 'Europe/Copenhagen' )
          AT TIME ZONE tzname

(F)
         ( TIMESTAMP '2018-01-01 00:00:00'
            AT TIME ZONE tzname )
          AT TIME ZONE 'Europe/Copenhagen'

论坛徽章:
20
2012新春纪念徽章
日期:2012-01-04 11:58:44秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-28 10:21:13秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-04-29 15:04:10秀才
日期:2016-04-29 15:10:43秀才
日期:2016-03-01 09:55:08
发表于 2018-1-9 08:20 | 显示全部楼层
正确答案:BCDF
A:会报日期格式无法识别的错误,TO_TIMESTAMP函数不能转换为时区
B:正确,TO_TIMESTAMP_TZ函数可以转换为时区
C:正确,Oracle 中的from_tz函数,可以将一个timstamp和timzone拼成一个timestamp with timezone(文档:FROM_TZ converts a timestamp value and a time zone to a TIMESTAMP WITH TIME ZONE value. time_zone_value is a character string in the format 'TZH:TZM' or a character expression that returns a string in TZR with optional TZD format.)
D:正确
E:错误,将哥本哈根的时间转换为了其他地区的时间。
F:正确,将其他地区的时间转换为哥本哈根的时间。

使用道具 举报

回复
认证徽章
论坛徽章:
0
发表于 2018-1-9 16:10 | 显示全部楼层
BCD吧

使用道具 举报

回复
论坛徽章:
486
秀才
日期:2015-09-09 10:33:01秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21秀才
日期:2016-01-06 14:10:21
 楼主| 发表于 2018-1-10 05:19 | 显示全部楼层
答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

A: TO_TIMESTAMP 函数返回的数据类型是TIMESTAMP, 而非 TIMESTAMP WITH TIME ZONE。因此我们不能用TZR,这个选项会报错:
ORA-01821: date format not recognized.         

B: 我们应该用的是TO_TIMESTAMP_TZ,它接受TZR格式,返回数据类型TIMESTAMP WITH TIME ZONE. 然后我们得到了所要的结果。

C: 前一选项的替代办法是用TO_TIMESTAMP来得到不带时区的TIMESTAMP信息,然后用FROM_TZ将TIMESTAMP转换成指定时区的TIMESTAMP WITH TIME ZONE

D: 我们可以不用前一选项的TO_TIMESTAMP,而是使用一个TIMESTAMP字面常量来达到同样目的。
E: 此处我们创建了一个TIMESTAMP字面常量,它被隐式转换成会话所在时区UTC的 TIMESTAMP WITH TIME ZONE。然后我们问这个时间点在Europe/Copenhagen 时区是什么时间,然后同样时间点在TZNAME的时区又是什么时间。所以我们得到的不是想要的输出,而是UTC午夜的时候在我的朋友的时区是什么时间:

FRIEND     TIME_FOR_SMS
---------- ----------------------------------------------------
Cecilia    2017-12-31 18:00:00 AMERICA/CHICAGO
Lucille    2018-01-01 00:00:00 EUROPE/LONDON
Patricia   2018-01-01 08:00:00 AUSTRALIA/PERTH

F: 我们创建的同样的TIMESTAMP字面常量再次被隐式转换成UTC午夜的时间点了。然后我们问这个时间点在TZNAME的时区是什么时间,然后同样时间点在Europe/Copenhagen时区又是什么时间。所以输出了UTC午夜在哥本哈根的时间:

FRIEND     TIME_FOR_SMS
---------- ----------------------------------------------------
Cecilia    2018-01-01 01:00:00 EUROPE/COPENHAGEN
Patricia   2018-01-01 01:00:00 EUROPE/COPENHAGEN
Lucille    2018-01-01 01:00:00 EUROPE/COPENHAGEN

使用道具 举报

回复
论坛徽章:
20
2012新春纪念徽章
日期:2012-01-04 11:58:44秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-28 10:21:13秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-04-29 15:04:10秀才
日期:2016-04-29 15:10:43秀才
日期:2016-03-01 09:55:08
发表于 2018-1-10 08:10 | 显示全部楼层
newkid 发表于 2018-1-10 05:19
答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

A: TO_TIMESTAMP 函数返回的数据类型是TIME ...

C:\Users\JohnLee\Desktop\题.png,我这里执行出来结果是正确的。

使用道具 举报

回复
论坛徽章:
20
2012新春纪念徽章
日期:2012-01-04 11:58:44秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-01 09:55:08秀才
日期:2016-03-28 10:21:13秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-03-28 10:30:00秀才
日期:2016-04-29 15:04:10秀才
日期:2016-04-29 15:10:43秀才
日期:2016-03-01 09:55:08
发表于 2018-1-10 08:18 | 显示全部楼层
本帖最后由 liwenrongdba 于 2018-1-10 08:20 编辑
newkid 发表于 2018-1-10 05:19
答案BCD,本期无人得奖。3楼请注意在自己答案加上简要说明。

A: TO_TIMESTAMP 函数返回的数据类型是TIME ...

F选项我这里执行出来是正确的,难道是我设置了nls_date_format?
SQL> alter session set time_zone='UTC';
Session altered

SQL>
SQL> select friend
  2       , to_char(
  3            ( TIMESTAMP '2018-01-01 00:00:00'
  4              AT TIME ZONE tzname )
  5            AT TIME ZONE 'Europe/Copenhagen'
  6          , 'YYYY-MM-DD HH24:MI:SS TZR'
  7         ) as time_for_sms
  8    from qz_friends
  9  order by time_for_sms
10  ;
FRIEND TIME_FOR_SMS
---------- ----------------------------------------------------
Patricia 2017-12-31 17:00:00 EUROPE/COPENHAGEN
Lucille 2018-01-01 01:00:00 EUROPE/COPENHAGEN
Cecilia 2018-01-01 07:00:00 EUROPE/COPENHAGEN

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

DTCC2018购票6.8折优惠进行时

中国数据库技术大会是国内数据库及大数据领域规模最大、最受欢迎的技术交流盛会。 2018年5月10-12日,第九届中国数据库技术大会将如约而至。本届大会以“数领先机•智赢未来”为主题,设定2大主会场及20个技术专场,邀请来自国内外互联网、金融、教育等行业百余位技术专家,共同探讨Oracle、MySQL、NoSQL、大数据等领域的前瞻性热点话题与技术。
----------------------------------------
优惠时间:2018年2月13日前

报名链接>>
TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 虎吧 老博客 知识索引树 读书频道 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛 | SAP ERP系统
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表