I want to convert Eastern time ("GMT-05:00") into IST ("GMT+05:30") in SQL Server 2008.
It should based on Bias & DayLightBias.
Ex: Eastern Time has Bias value 300 & DaylightBias value -60 & IST has Bias value -330 & DayLightBias value -60.
I know how to convert this in C# but I want to create a job and for that I need this conversion in SQL Server.
Use the DATETIMEOFFSET datatype and the SWITCHOFFSET method in SQL Server 2008 or newer:
-- define your input in Eastern Time
DECLARE #Input DATETIMEOFFSET = SYSDATETIME()
-- SET #Input = SWITCHOFFSET(#Input, '-05:00')
SET #Input = SWITCHOFFSET(#Input, -300)
DECLARE #output DATETIMEOFFSET
-- convert Eastern Time to IST
-- SET #output = SWITCHOFFSET(#input, '+05:30')
SET #output = SWITCHOFFSET(#input, 330)
SELECT #Input, #output
MSDN SQL Server Books Online documentation for DATETIMEOFFSET
MSDN SQL Server Books Online documentation for SWITCHOFFSET
There are a lot more things to consider other than just the base offset and dst bias. Specifically, different offsets switch between standard and daylight time on different dates and at different times.
The correct way is with a named time zone. Unlike many other databases, SQL Server does not have native support for time zones. It only has support for time zone offsets. See "Time Zone != Offset" in the timezone tag wiki.
Fortunately, I've done all the hard work for you. Using my SQL Server Time Zone Support project, you can write this query:
SELECT Tzdb.ConvertZone(yourDateTimeValue, 'America/New_York', 'Asia/Kolkata', 1, 1)
The time zones are standard IANA tz database identifiers, and the numerical options at the end are explained in the project's readme.
Related
I have database table that has datetime field in SQL Server.
I have to send as below sample.
Can you please help how to get this dateformat?
Example: 2020-06-10T13:11:00-05:00
Thanks
If you were on a supported version of SQL Server, this is actually quite trivial. If we assume the value in the table is 2020-06-10T13:11:00 it would just need a CONVERT and SWITCHOFFSET:
SELECT V.Dt,
SWITCHOFFSET(CONVERT(datetimeoffset(0),V.dt),'-05:00')
FROM (VALUES(CONVERT(datetime2(0),'2020-06-10T13:11:00')))V(Dt);
If it's actually a UTC time, and you need to change it to (I assume) Central, then it would be:
SELECT V.Dt,
CONVERT(datetimeoffset(0),V.dt) AT TIME ZONE 'Central Standard Time'
FROM (VALUES(CONVERT(datetime2(0),'2020-06-10T18:11:00')))V(Dt);
Instead, you're going to have to do some varchar manipulation, as you're using a version of SQL Server that is completely unsupported:
--If switching the offset
SELECT V.Dt,
CONVERT(datetimeoffset(0),CONVERT(varchar(20),V.Dt,126) + '-05:00')
FROM (VALUES(CONVERT(datetime2(0),'2020-06-10T13:11:00')))V(Dt);
--If changing the offset
SELECT V.Dt,
CONVERT(datetimeoffset(0),CONVERT(varchar(20),DATEADD(HOUR, -5,V.Dt),126) + '-05:00')
FROM (VALUES(CONVERT(datetime2(0),'2020-06-10T18:11:00')))V(Dt);
Note that both of these are DST agnositic, as it SWITCHOFFSET. Only AT TIME ZONE will consider the DST.
We are dealing with an application that needs to handle global time data from different time zones and daylight savings time settings. The idea is to store everything in UTC format internally and only convert back and forth for the localized user interfaces. Does the SQL Server offer any mechanisms for dealing with the translations given a time, a country and a timezone?
This must be a common problem, so I'm surprised google wouldn't turn up anything usable.
Any pointers?
This works for dates that currently have the same UTC offset as SQL Server's host; it doesn't account for daylight savings changes. Replace YOUR_DATE with the local date to convert.
SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);
7 years passed and...
actually there's this new SQL Server 2016 feature that does exactly what you need.
It is called AT TIME ZONE and it converts date to a specified time zone considering DST (daylight saving time) changes.
More info here:
https://msdn.microsoft.com/en-us/library/mt612795.aspx
While a few of these answers will get you in the ballpark, you cannot do what you're trying to do with arbitrary dates for SqlServer 2005 and earlier because of daylight savings time. Using the difference between the current local and current UTC will give me the offset as it exists today. I have not found a way to determine what the offset would have been for the date in question.
That said, I know that SqlServer 2008 provides some new date functions that may address that issue, but folks using an earlier version need to be aware of the limitations.
Our approach is to persist UTC and perform the conversion on the client side where we have more control over the conversion's accuracy.
Here is the code to convert one zone DateTime to another zone DateTime
DECLARE #UTCDateTime DATETIME = GETUTCDATE();
DECLARE #ConvertedZoneDateTime DATETIME;
-- 'UTC' to 'India Standard Time' DATETIME
SET #ConvertedZoneDateTime = #UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time'
SELECT #UTCDateTime AS UTCDATE,#ConvertedZoneDateTime AS IndiaStandardTime
-- 'India Standard Time' to 'UTC' DATETIME
SET #UTCDateTime = #ConvertedZoneDateTime AT TIME ZONE 'India Standard Time' AT TIME ZONE 'UTC'
SELECT #ConvertedZoneDateTime AS IndiaStandardTime,#UTCDateTime AS UTCDATE
Note: AT TIME ZONE works only on SQL Server 2016+ and the advantage is that it automatically considers Daylight when converting to a particular Time zone
For SQL Server 2016 and newer, and Azure SQL Database, use the built in AT TIME ZONE statement.
For older editions of SQL Server, you can use my SQL Server Time Zone Support project to convert between IANA standard time zones, as listed here.
UTC to Local is like this:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')
Local to UTC is like this:
SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)
The numeric options are flag for controlling the behavior when the local time values are affected by daylight saving time. These are described in detail in the project's documentation.
SQL Server 2008 has a type called datetimeoffset. It's really useful for this type of stuff.
http://msdn.microsoft.com/en-us/library/bb630289.aspx
Then you can use the function SWITCHOFFSET to move it from one timezone to another, but still keeping the same UTC value.
http://msdn.microsoft.com/en-us/library/bb677244.aspx
Rob
I tend to lean towards using DateTimeOffset for all date-time storage that isn't related to a local event (ie: meeting/party, etc, 12pm-3pm at the museum).
To get the current DTO as UTC:
DECLARE #utcNow DATETIMEOFFSET = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
DECLARE #utcToday DATE = CONVERT(DATE, #utcNow);
DECLARE #utcTomorrow DATE = DATEADD(D, 1, #utcNow);
SELECT #utcToday [today]
,#utcTomorrow [tomorrow]
,#utcNow [utcNow]
NOTE: I will always use UTC when sending over the wire... client-side JS can easily get to/from local UTC. See: new Date().toJSON() ...
The following JS will handle parsing a UTC/GMT date in ISO8601 format to a local datetime.
if (typeof Date.fromISOString != 'function') {
//method to handle conversion from an ISO-8601 style string to a Date object
// Date.fromISOString("2009-07-03T16:09:45Z")
// Fri Jul 03 2009 09:09:45 GMT-0700
Date.fromISOString = function(input) {
var date = new Date(input); //EcmaScript5 includes ISO-8601 style parsing
if (!isNaN(date)) return date;
//early shorting of invalid input
if (typeof input !== "string" || input.length < 10 || input.length > 40) return null;
var iso8601Format = /^(\d{4})-(\d{2})-(\d{2})((([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d{1,12}))?)?)?)?)?([Zz]|([-+])(\d{2})\:?(\d{2}))?$/;
//normalize input
var input = input.toString().replace(/^\s+/,'').replace(/\s+$/,'');
if (!iso8601Format.test(input))
return null; //invalid format
var d = input.match(iso8601Format);
var offset = 0;
date = new Date(+d[1], +d[2]-1, +d[3], +d[7] || 0, +d[8] || 0, +d[10] || 0, Math.round(+("0." + (d[12] || 0)) * 1000));
//use specified offset
if (d[13] == 'Z') offset = 0-date.getTimezoneOffset();
else if (d[13]) offset = ((parseInt(d[15],10) * 60) + (parseInt(d[16],10)) * ((d[14] == '-') ? 1 : -1)) - date.getTimezoneOffset();
date.setTime(date.getTime() + (offset * 60000));
if (date.getTime() <= new Date(-62135571600000).getTime()) // CLR DateTime.MinValue
return null;
return date;
};
}
Yes, to some degree as detailed here.
The approach I've used (pre-2008) is to do the conversion in the .NET business logic before inserting into the DB.
You can use GETUTCDATE() function to get UTC datetime
Probably you can select difference between GETUTCDATE() and GETDATE() and use this difference to ajust your dates to UTC
But I agree with previous message, that it is much easier to control right datetime in the business layer (in .NET, for example).
SUBSTRING(CONVERT(VARCHAR(34), SYSDATETIMEOFFSET()), 29, 5)
Returns (for example):
-06:0
Not 100% positive this will always work.
Sample usage:
SELECT
Getdate=GETDATE()
,SysDateTimeOffset=SYSDATETIMEOFFSET()
,SWITCHOFFSET=SWITCHOFFSET(SYSDATETIMEOFFSET(),0)
,GetutcDate=GETUTCDATE()
GO
Returns:
Getdate SysDateTimeOffset SWITCHOFFSET GetutcDate
2013-12-06 15:54:55.373 2013-12-06 15:54:55.3765498 -08:00 2013-12-06 23:54:55.3765498 +00:00 2013-12-06 23:54:55.373
I always use this code for conversion in datetime:
DECLARE #a datetime
SET #a= CONVERT(datetime,'2012-12-28 14:04:43')
print #a
But this does not work anymore! I tried even restarting SQL Server, but the problem remains:
The error in the image is in Italian. In English should be:
The conversion of a char data type to datetime resulted in a datetime
value that is out of range of allowed values.
There are many formats supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependant on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
So in your concrete case - use this:
DECLARE #a datetime
SET #a= CONVERT(datetime, '2012-12-28T14:04:43')
print #a
and this should work on any SQL Server installation, with any language and date format settings.
If you run your original code for US English - it will work just fine:
SET LANGUAGE English
DECLARE #a datetime
SET #a= CONVERT(datetime, '2012-12-28 14:04:43')
print #a
Dec 28 2012 2:04PM
but if you use Italian (or German, or British, or French) as your language, it will fail because the format without the T in the middle of the date/time string is NOT language-independent and not "safe" :
SET LANGUAGE Italian
DECLARE #a datetime
SET #a= CONVERT(datetime, '2012-12-28 14:04:43')
print #a
Msg 242, Level 16, State 3, Line 4
La conversione di un tipo di dati varchar in datetime ha generato un valore non compreso nell'intervallo dei valori consentiti.
You are trying to convert a string to a datetime. Problem is with the date part. Best way is to get the date string into ISO format (yyyymmdd) and then convert. Try this;
DECLARE #a datetime
SET #a= CONVERT(datetime,replace('2012-12-28 14:04:43', '-',''))
print #a
My guess is that the default date time format changed on your computer. Add the conversion specification back in:
SET #a= CONVERT(datetime,'2012-12-28 14:04:43', 121)
How to compare Indian time with world's other country times in SQL Server 2008?
Means i want to know if in India its mid night 1 am what will be timing in other countries through SQL Server 2008
SQL Server 2008 uses the DateTimeOffset type to represent DateTime with a timezone offset.
You can convert values from one timezone to another using the SWITCHOFFSET function.
To create DateTimeOffset values for a specific timezone from existing date values, use TODATETIMEOFFSET.
You can get the current date and time including the offset using SYSDATETIMEOFFSET.
Finally, you can use plain-old DATEDIFF to compare DateTimeOffset values and get their difference.
To get your current time in India and switch it to another timezone you have to know the proper time offset. The statement would be something like
DECLARE #localTime DATETIMEOFFSET=SYSDATETIMEOFFSET()
SELECT #localTime, SWITCHOFFSET(#localTime,'-5:00')
Have a look at SYSUTCDATETIME():
SELECT SYSDATETIME(), SYSUTCDATETIME();
With UTC Time you can easily calculate the time in any other country.
DECLARE #indianTime DATETIME = GETDATE()
DECLARE #timeZoneOffset SMALLINT = 3 -- or -3
SELECT DATEADD(hour, #timeZoneOffset, #indianTime)
See next MSDN articles: 1, 2
But it's better to use SQL Server 2008 and DateTimeOffset type which supports time zones.
So you could do next:
DECLARE #indianTime DATETIME = SYSDATETIMEOFFSET()
DECLARE #timeZoneOffset NVARCHAR(6) = '-03:00'
SELECT SWITCHOFFSET(#indianTime, #timeZoneOffset)
I would like to know which format SQL Server saves datetimes, GMT or UMT?
The default DATETIME value in SQL Server has no knowledge of time zones and thus doesn't really care about time zones - that's entirely up to you to manage.
DECLARE #MyDate DATETIME
SET #MyDate = '20100922 04:05:06' --- no information on timezone
See MSDN docs on DATETIME.
With SQL Server 2008, a new data type was introduced called DATETIMEOFFSET which stores time along with a timezone offset. So here, you can store the local time and store the timezone that time is local to as well.
DECLARE #MyDateOffset DATETIMEOFFSET
SET #MyDateOffset = '20100922 04:05:06 +09:00' -- UTC plus 9 hours
Neither, it just returns the values in a specific format but stores it in a format without a timezone.