I need to format a set of dates in SQL server to the following format..
yyyy-MM-ddThh:mm:ssZ
I cant seem to find how to format the date with the T and Z parts included in the string
Any ideas how to achieve this format in a SQL query?
According to the SQL Server 2005 books online page on Cast and Convert you use date format 127 - as per the example below
CONVERT(varchar(50), DateValueField, 127)
SQL Server 2000 documentation makes no reference to this format - perhaps it is only available from versions 2005 and up.
Note on the time zone added to the end (from note 7 in the docs): The optional time zone indicator, Z, is used to make it easier to map XML datetime values that have time zone information to SQL Server datetime values that have no time zone. Z is the indicator for time zone UTC-0. Other time zones are indicated with HH:MM offset in the + or - direction. For example: 2006-12-12T23:45:12-08:00.
Thanks to Martin for this note: You should be able to use STUFF to remove the miliseconds as these will be in a fixed position from the left of the string. i.e.
SELECT STUFF(CONVERT(VARCHAR(50),GETDATE(), 127) ,20,4,'')
DECLARE #SampleDate DATETIME2(3) = '2020-07-05 23:59:59';
SELECT CONVERT(VARCHAR(20), CONVERT(DATETIMEOFFSET, #SampleDate), 127);
--results: 2020-07-05T23:59:59Z
You can parse C# output in SQL using below:
SELECT CONVERT(DATETIME, CONVERT(DATETIMEOFFSET,'2017-10-27T10:44:46Z'))
Use C# to generate this using the following:
string ConnectionString = "Data Source=SERVERNAME; Initial Catalog=DATABASENAME; Persist Security Info=True; User ID=USERNAME; Password=PASSWORD";
using(SqlConnection conn = new SqlConnection(ConnectionString))
{
DateTime d = DateTime.Now;
string Query = "SELECT CONVERT(DATETIME, CONVERT(DATETIMEOFFSET,'" + d.ToString("yyyy-MM-dd") + "T" + d.ToString("HH:mm:ss") + "Z'))"
conn.Open();
using(SqlCommand cmd = new SqlCommand(Query, conn))
{
using(SqlDataReader rdr = cmd.ExecuteReader())
{
if(rdr.HasRows)
{
while(rdr.Read())
{
for(int i; i < rdr.length; i++)
{
Console.WriteLine(rdr[0].ToString());
}
}
//DataTable dt = new DataTable(); dt.Load(rdr); //Alternative method if DataTable preferred
}
}
}
}
select left(convert(varchar(30),getdate(),126)+ '.000',23)
Try this
SELECT STUFF(
CONVERT(datetime2(0), GETDATE(), 126)
AT TIME ZONE 'US Eastern Standard Time'
,11,1,'T')
on MSSQL
SELECT FORMAT( GETDATE(),'yyyy-MM-ddTHH:mm:ss.ms zzzz')
Related
I ran into something that seems odd. SQL Server appears to be rounding some DateTime values inappropriately when I save them to datetime columns. I suspect I'm missing something, but I can't spot it. I'm running this test against SQL Server 2008 using .NET 4.0. The following should illustrate the issue:
I have created a table in in SQL Server called Timestamps. It has two columns:
id - bigint, Identity, PK
timestamp - datetime
I also created a simple test that does the following:
Gets the current time, truncating the value to millisecond precision
Saved the truncated time to Timestamps
Retrieved the datetime` value from the DB and compared it to the original (truncated) DateTime object.
public static void RoundTest()
{
DateTime preTruncation = DateTime.UtcNow;
DateTime truncated = preTruncation.TruncateToMilliseconds();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["test"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(#"INSERT INTO Timestamps(timestamp)
VALUES(#savedTime);
SELECT SCOPE_IDENTITY() AS id");
cmd.Parameters.Add(new SqlParameter("savedTime", truncated));
cmd.Connection = conn;
var id = cmd.ExecuteScalar();
SqlCommand get = new SqlCommand(#"SELECT timestamp FROM Timestamps
WHERE id = #id");
get.Parameters.Add(new SqlParameter("id", id));
get.Connection = conn;
DateTime retrieved = (DateTime)get.ExecuteScalar();
if (retrieved != truncated)
{
Console.WriteLine("original: " + preTruncation.TimeOfDay);
Console.WriteLine("truncated: " + truncated.TimeOfDay);
Console.WriteLine("retrieved: " + retrieved.TimeOfDay);
Console.WriteLine();
}
}
}
Although I expect the truncated value to be equivalent to the value returned back from the DB, that is not always the case. Here's some sample output:
original: 19:59:13.4049965
truncated: 19:59:13.4040000
retrieved: 19:59:13.4030000
original: 19:59:14.4989965
truncated: 19:59:14.4980000
retrieved: 19:59:14.4970000
original: 19:59:15.4749965
truncated: 19:59:15.4740000
retrieved: 19:59:15.4730000
original: 19:59:30.1549965
truncated: 19:59:30.1540000
retrieved: 19:59:30.1530000
TruncateToMilliseconds() looks like this:
public static DateTime TruncateToMilliseconds(this DateTime t)
{
return new DateTime(t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Millisecond);
}
What gives? Is this really inappropriate rounding, or am I making a mistaken assumption here?
Datetime is only accurate to 3ms. Therefore it'll round to the nearest multiple of 3ms. To overcome this, look at the datetime2. Note that this is for SQL2008+ only
EDIT: it's not quite only to 3ms. It's rounded to increments of of .000, .003, or .007 seconds
I am aware that there are differences between Oracle SQL and SQL Server. The query runs fine and displays the result well but the issue arises when I want to display it on a pie chart. I am thinking that it might be some Visual Studio restriction.
Here is my SQL statement:
SELECT
CAST(ROUND(CAST(COUNT(LoanAcNo) AS FLOAT) / 73 * 100, 1) AS VARCHAR) + '%' AS LoanPercentage,
LoanType
FROM
Loan
GROUP BY
LoanType;
This is how I implemented it:
public DataSet ReadLoanByLoanType()
{
SqlConnection myConn = new SqlConnection(DBConnect);
StringBuilder sqlStr = new StringBuilder();
sqlStr.AppendLine("SELECT cast( round( cast ( count(LoanAcNo) as float) / 73 * 100 , 1 ) as varchar ) + '%' as LoanPercentage , LoanType");
sqlStr.AppendLine("FROM Loan");
sqlStr.AppendLine("GROUP BY LoanType");
SqlDataAdapter da = new SqlDataAdapter(sqlStr.ToString(), myConn);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
If you want to download values from a database for inclusion in some reporting tool's pie chart, don't turn the value into a string by adding a '%' onto them
Your reports tool will be expecting some numeric value to chart, not a string
SQL:
SELECT
round(count(LoanAcNo)/ 73.0 * 100.0, 1) as LoanPercentage,
LoanType
FROM Loan
GROUP BY LoanType;
Tip: dividing an integer by a constant number that has a decimal place (e.g. I divided by 73.0 instead of 73) rather than an integer should make SQLS do the calc using floats - saves you having to cast the int to float/makes the SQL shorter and neater
Hi i am pulling the date from sql server which returns this: 12/19/2014 4:17:31 PM
However I only want it to return 12/19/2014
I am using this to get the order date: txtOrderDate.Text = dt.Rows(0).Item("OrderDate")
How do I convert this to only return the date in this format MM/dd/YYYY?
I cannot do it using the SQL Statement because I am pulling other columns as well.
Thanks
You could get the output desidered with
Dim dt as DateTime
if Not dt.Rows(0).IsNull("OrderDate") _
AndAlso DateTime.TryParse(dt.Rows(0).Item("OrderDate"), _
CultureInfo.InvariantCulture, _
DateTimeStyles.None, dt) Then
txtOrderDate.Text = dt.ToString("MM/dd/yyyy")
else
.... ' Something to do in case of null or invalid date
End If
The use of DataRow.IsNull and DateTime.TryParse is a precautionary step to avoid any possible exception in case your column "OrderDate" is null or not in a correct format.
I think this will work:
txtOrderDate.Text = dt.Rows(0).Item("OrderDate").ToString("MM/dd/yyyy")
However, it's been a while since I've had to work with DataTable cells directly; there's a chance the above code will only have the Object type, rather than the VB.Net DateTime type, and therefore that .ToString() overload won't be available. If that's the case, do this instead:
txtOrderDate.Text = DirectCast(dt.Rows(0).Item("OrderDate"), DateTime).ToString("MM/dd/yyyy")
I ran into something that seems odd. SQL Server appears to be rounding some DateTime values inappropriately when I save them to datetime columns. I suspect I'm missing something, but I can't spot it. I'm running this test against SQL Server 2008 using .NET 4.0. The following should illustrate the issue:
I have created a table in in SQL Server called Timestamps. It has two columns:
id - bigint, Identity, PK
timestamp - datetime
I also created a simple test that does the following:
Gets the current time, truncating the value to millisecond precision
Saved the truncated time to Timestamps
Retrieved the datetime` value from the DB and compared it to the original (truncated) DateTime object.
public static void RoundTest()
{
DateTime preTruncation = DateTime.UtcNow;
DateTime truncated = preTruncation.TruncateToMilliseconds();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["test"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(#"INSERT INTO Timestamps(timestamp)
VALUES(#savedTime);
SELECT SCOPE_IDENTITY() AS id");
cmd.Parameters.Add(new SqlParameter("savedTime", truncated));
cmd.Connection = conn;
var id = cmd.ExecuteScalar();
SqlCommand get = new SqlCommand(#"SELECT timestamp FROM Timestamps
WHERE id = #id");
get.Parameters.Add(new SqlParameter("id", id));
get.Connection = conn;
DateTime retrieved = (DateTime)get.ExecuteScalar();
if (retrieved != truncated)
{
Console.WriteLine("original: " + preTruncation.TimeOfDay);
Console.WriteLine("truncated: " + truncated.TimeOfDay);
Console.WriteLine("retrieved: " + retrieved.TimeOfDay);
Console.WriteLine();
}
}
}
Although I expect the truncated value to be equivalent to the value returned back from the DB, that is not always the case. Here's some sample output:
original: 19:59:13.4049965
truncated: 19:59:13.4040000
retrieved: 19:59:13.4030000
original: 19:59:14.4989965
truncated: 19:59:14.4980000
retrieved: 19:59:14.4970000
original: 19:59:15.4749965
truncated: 19:59:15.4740000
retrieved: 19:59:15.4730000
original: 19:59:30.1549965
truncated: 19:59:30.1540000
retrieved: 19:59:30.1530000
TruncateToMilliseconds() looks like this:
public static DateTime TruncateToMilliseconds(this DateTime t)
{
return new DateTime(t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Millisecond);
}
What gives? Is this really inappropriate rounding, or am I making a mistaken assumption here?
Datetime is only accurate to 3ms. Therefore it'll round to the nearest multiple of 3ms. To overcome this, look at the datetime2. Note that this is for SQL2008+ only
EDIT: it's not quite only to 3ms. It's rounded to increments of of .000, .003, or .007 seconds
The following is a simplied version of a query that a reporting tool is sending to our database. I have never seen this syntax before in the Where clause. Can someone tell me what the brackets are doing? And, I assume the 'd' acts as a date cast?
Select
ch.ContainerID,
ch.WorkItemHistoryEventTypeEnumID,
ch.EventTime,
ch.ContainerBinName,
ch.WorkItemSerialNumber,
ch.Closed
From Wip.vwContainerHistory ch
Where
ch.EventTime >= {d '2010-08-09'}
See "Supported String Literal Formats for datetime" section in MSDN datetime article.
Your {d 'XXXX-XX-XX'} is ODBC datetime format. ODBC timestamp escape sequences are of the format: { literal_type 'constant_value' }:
literal_type specifies the type of the escape sequence. Timestamps have three literal_type specifiers:
d = date only
t = time only
ts = timestamp (time + date)
'constant_value' is the value of the escape sequence. constant_value must follow these formats for each literal_type.
d > yyyy-mm-dd
t > hh:mm:ss[.fff]
ts > yyyy-mm-dd hh:mm:ss[.fff]
This is an ODBC escape sequence for a date type. See http://msdn.microsoft.com/en-us/library/ms187819.aspx
d = date only
t = time only
ts = timestamp (time + date)