【问题标题】:Date conversion from "JAN02/19 to 2019-01-02从“JAN02/19 到 2019-01-02”的日期转换
【发布时间】:2020-01-15 16:32:05
【问题描述】:

如何将 varchar(25) 列的值从“JAN02/19”格式的日期转换为“2019-01-02”(YYYY-MM-DD)?

【问题讨论】:

  • 每次你认为你已经看到了人们能想到的每一种糟糕的日期格式时......都会有一个新的。 :-P SELECT CONVERT(DATE, SUBSTRING('JAN02/19', 4, 2) + STUFF('JAN02/19', 4, 3, ''), 6)。如果可以,请将其保留为DATE(或DATETIME),不要尝试再次将其格式化回数据库中的字符串——这应该是客户的责任。
  • 我强烈建议将列的类型更改为datetime,而不是将日期存储为字符串。然后你可以让任何显示日期选择格式。
  • 你为什么认为 string 指的是 2019 年?毕竟艾萨克·阿西莫夫出生于 1920 年。你有一个非常严重的问题,没有任何借口。您应该尽快将该字段更改为datedatetime2
  • @JeroenMostert 成功了,感谢您关于不格式化回字符串的建议。
  • @DStanley 感谢您提出将列数据类型更改为日期的建议。

标签: sql sql-server 2-digit-year y2k


【解决方案1】:

大概是这样的

Declare @S varchar(25)='JAN02/19'

Select try_convert(date,replace(@S,'/',' 20'))

返回

2019-01-02

【讨论】:

  • 需要注意的一点:第 58 年将是 2058 年而不是 1958 年 - 仅举例(78 也是,88 也是,...)
  • @VBoka 让我们希望 OP 尚未存储任何生产数据,并更改列类型而不是仅更改查询。
  • @VBoka 没有具体说明,但很有可能这是当前世纪。如果没有,那么很容易捕获未来的日期。
  • 这就是为什么我只是写了一个小笔记:)
【解决方案2】:

您可以执行以下操作:

DECLARE @Date Varchar(10)
Set @Date='JAN02/19'
select DATEFROMPARTS('20'+substring(@Date,7,2),CHARINDEX(@Date,'JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC')/4+1,substring(@Date,4,2))

这应该以所需的格式提供输出。

编辑:

为了适应不正确的月份值:

DECLARE @Date Varchar(10)
Set @Date='JAN02/19'
select DATEFROMPARTS('20'+substring(@Date,7,2),NULLIF(CHARINDEX(substring(@Date,1,3),'JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC'),0)/4+1,substring(@Date,4,2))

如果月份值不正确,这将返回 NULL。

【讨论】:

  • 一个明确的方法——我唯一的烦恼是,对于无效的月份名称,这会返回一个将月份设置为一月的日期,而不是抱怨。
  • 现在它只是笨重。 :-) 我建议使用NULLIF(CHARINDEX(substring(@Date,1,3),'JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC'), 0) 来避免重复表达。 NULLIF 和空传播很漂亮。
  • 编辑了使用NULLIF的答案...感谢@Jeroen的建议
猜你喜欢
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多