我需要在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 |
+-------------------------+-------------------------+-------------------------+-------------------------+-------------------------+
答案 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 type和sql 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。