如何在使用Parse功能时控制日历系统?

时间:2016-12-05 18:08:21

标签: sql-server tsql sql-server-2012

我需要在SQL Server中将字符串转换为基于.net DateTime类型在不同文化中格式化的日期时间。我可以使用SQL Server parse函数轻松地为大多数文化做到这一点。

SELECT
PARSE(N'4/22/1996 11:00:00 PM' AS DATETIME USING 'en-US' ),
PARSE(N'6/7/2016' AS DATETIME USING 'en-US' ),
PARSE(N'1/2/2016' AS DATETIME USING 'en-US' ),
PARSE(N'2/1/2016' AS DATETIME USING 'en-US' ),
PARSE(N'1:00:00 AM' AS DATETIME USING 'en-US' )

输出:

+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+
| 1996-04-22 23:00:00.000 | 2016-06-07 00:00:00.000 | 2016-01-02 00:00:00.000 | 2016-02-01 00:00:00.000 | 2016-12-05 01:00:00.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+

对于非默认情况下基于格里历日历系统的文化,我无法弄清楚如何告诉Parse功能使用哪个日历系统。

例如,对于ar-SA,默认日历系统为 hijri 。我可以使用解析函数,因为日期是hijri日期:

SELECT
PARSE(N'05/12/16 11:00:00 م' AS DATETIME USING 'ar-SA' ),
PARSE(N'02/09/37' AS DATETIME USING 'ar-SA' ),
PARSE(N'22/03/37' AS DATETIME USING 'ar-SA' ),
PARSE(N'22/04/37' AS DATETIME USING 'ar-SA' ),
PARSE(N'01:00:00 ص' AS DATETIME USING 'ar-SA' )

输出:

+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+
| 1996-04-22 23:00:00.000 | 2016-06-07 00:00:00.000 | 2016-01-02 00:00:00.000 | 2016-02-01 00:00:00.000 | 2016-12-05 01:00:00.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+

但是,我使用 Gregorian 日历系统在ar-SA格式化了我的字符串。

当我尝试使用解析函数

转换它们时
SELECT
PARSE(N'22/04/1996 11:00:00 م' AS DATETIME USING 'ar-SA' ),
PARSE(N'07/06/2016' AS DATETIME USING 'ar-SA' ),
PARSE(N'02/01/2016' AS DATETIME USING 'ar-SA' ),
PARSE(N'01/02/2016' AS DATETIME USING 'ar-SA' ),
PARSE(N'01:00:00 ص' AS DATETIME USING 'ar-SA' )

我收到以下错误:

  

使用culture'ar-SA'将字符串值'22 / 04/1996 11:00:00م'转换为数据类型datetime时出错。

但我需要一种方法来告诉解析字符串日期时间所在的日历系统,以便得到预期的输出:

+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+
| 1996-04-22 23:00:00.000 | 2016-06-07 00:00:00.000 | 2016-01-02 00:00:00.000 | 2016-02-01 00:00:00.000 | 2016-12-05 01:00:00.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+

有没有办法调用解析函数并告诉SQL Server哪个日历系统与文化一起使用?

更新

转换不起作用。它不处理阿拉伯语am / pm指定,也假设hijri日历系统。

SELECT
CONVERT(datetime, N'22/04/1996 11:00:00 م', 131 ),
CONVERT(datetime, N'07/06/2016', 131 ),
CONVERT(datetime, N'02/01/2016', 131 ),
CONVERT(datetime, N'01/02/2016', 131 ),
CONVERT(datetime, N'01:00:00 ص', 131 )

输出:

  

从字符串转换日期和/或时间时转换失败。

当非Aribic AM PM指定仍然使用Hijiri日历系统时

SELECT
CONVERT(datetime, N'22/04/1996 11:00:00 pm', 131 ),
CONVERT(datetime, N'07/06/2016', 131 ),
CONVERT(datetime, N'02/01/2016', 131 ),
CONVERT(datetime, N'01/02/2016', 131 ),
CONVERT(datetime, N'01:00:00 am', 131 )

导致日期完全错误:

+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+
| 2558-06-10 23:00:00.000 | 2577-12-18 00:00:00.000 | 2577-07-18 00:00:00.000 | 2577-08-16 00:00:00.000 | 1900-01-01 01:00:00.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+

1 个答案:

答案 0 :(得分:0)

有没有办法调用解析函数并告诉SQL Server哪个日历系统与文化一起使用? 不,但您可以将语言更改为'British'以切换到格里历日历。

我无法用阿拉伯语am / pm解析格里高利日期,所以所有这些都用am / pm替换了。

例如:http://rextester.com/ZVAG17162

if exists (select * from tempdb.sys.objects where name like '#Hijri%') begin; drop table #Hijri; end;
create table #Hijri (strIn nvarchar(32) 
                   , amPm nvarchar(32))
/* Hijri Format & Gregorian Calendar */ insert into  #Hijri (strIn) values (N'22/04/1996 11:00:00 م'),(N'07/06/2016'),(N'02/01/2016'),(N'01/02/2016'),(N'01:00:00 ص')
/* Hijri Format & Hijri Calendar */  --insert into  #Hijri (strIn) values (N'05/12/16 11:00:00 م') ,(N'02/09/37') ,(N'22/03/37') ,(N'22/04/37') ,(N'01:00:00 ص') 
update #Hijri set amPm = replace(replace(strIn,N' م',N' pm'),N' ص',N' am');
--set language 'Arabic';  /* implies Hijri Calendar                                            */
--set language 'English'; /* implies Gregorian Calendar & implicitly sets dateformat mdy       */
set language 'British';   /* implies Gregorian Calendar & implicitly sets dateformat dmy       */
--set dateformat mdy;     /* requires style 103 on convert, overrides language default         */
--set dateformat dmy;     /* does not require style 103 on convert, overrides language default */

select 
    strIn
  , amPm
  , GregorianCalendarDateTime     =convert(datetime2(2),amPm,103)
  --/*  -- requires: set language 'British'; -- or other gregorian calendar culture -- else converts to Hijri Calendar
  , HijriFormatGregorianCalendar  =replace(replace(
                                  format(convert(datetime2(2),amPm,103), N'dd/MM/yyyy hh:mm:ss tt') 
                                  ,N' PM',N' م'),N' AM',N' ص')   --*/
  , HijriFormatHijriCalendar      =format(convert(datetime2(2),amPm,103), N'dd/MM/yyyy hh:mm:ss tt', 'ar-SA' )
  , HijriCalendarDateString       =convert(nvarchar(32),convert(datetime2(2),amPm,103),131)
  --/* -- requires: set language 'Arabic' or 'British'; or set dateformat dmy;
  , HijriCalendarDateTime         =convert(datetime2(2),(convert(nvarchar(32),convert(datetime2(2),amPm,103),131)),103)  --*/
  from #Hijri;

对评论的回应:“只是想知道你是否有链接,你可以指出我说日历系统无法控制?” data,datetime,datetime2和datetimeoffset数据类型不存储可变日历类型,它们是Gregorian日历。当您看到一个hijri日期时间时,您会看到一个应用于8字节日期时间值(或x字节datetime2值)的格式。

sql server datetime data typesql server datetime2 data type

的参考链接

即使DateTime in .NET Framework 4.6.2正在使用公历。

// This value type represents a date and time.  Every DateTime 
// object has a private field (Ticks) of type Int64 that stores the 
// date and time as the number of 100 nanosecond intervals since 
// 12:00 AM January 1, year 1 A.D. in the proleptic Gregorian Calendar.

.NET Framework DateTime Constructor仅使用Calendar参数来解释年,月和日。

parse与culture参数一起使用时,用于标识表示日期时间值的字符串值的格式。正如convert采用确定字符串值的标准(格式)的样式参数一样使用它。特别是对于阿拉伯文化'ar-SA'和样式130和131,SQL Server使用Kuwaiti algorithm