Why is SQL Server 2017 not recognizing AT Time zone? - timezone

I'm running the following query on a SQL server 2017 Database (developer edition). the query executes but it only shows the getdate value without actually converting. I also see that "AT TIME ZONE" is no fully highlighted in blue by the SQL editor, which means it is probably not recognized. Any idea please?
SELECT
GETDATE() AT TIME ZONE 'Central Europe Standard Time' as CET,
GETDATE() AT TIME ZONE 'Cuba Standard Time' as 'Cuba Time'
P.S: I checked that time zones are defined and spelled correctly
SELECT * FROM sys.time_zone_info

It seems the problem is your misunderstanding of how AT TIME ZONE works with a datetime datatype (which is what GETDATE() returns). Take the following:
DECLARE #DT datetime = '2020-01-17T16:39:01.123';
SELECT #DT AT TIME ZONE 'Central Europe Standard Time' as CET,
#DT AT TIME ZONE 'Cuba Standard Time' as [Cuba Time];
This returns the below:
CET Cuba Time
---------------------------------- ----------------------------------
2020-01-17 16:39:01.123 +01:00 2020-01-17 16:39:01.123 -05:00
Notice the times are the same as what is was in #DT apart from the timezone. This is because datetime is timezone agnostic; it doesn't know that exist. As a result the timezone is simply "added on" to the value.
If you use a datetimeoffset, however, you get the result you expect:
DECLARE #DT datetimeoffset(0) = '2020-01-17T16:39:01.123';
SELECT #DT AT TIME ZONE 'Central Europe Standard Time' as CET,
#DT AT TIME ZONE 'Cuba Standard Time' as [Cuba Time];
Returns:
CET Cuba Time
---------------------------------- ----------------------------------
2020-01-17 17:39:01 +01:00 2020-01-17 11:39:01 -05:00
In your case, that means instead you need to use SYSDATETIMEOFFSET:
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'Central Europe Standard Time' as CET,
SYSDATETIMEOFFSET() AT TIME ZONE 'Cuba Standard Time' as [Cuba Time];
For me, as I write this answer, that returns the below:
CET Cuba Time
---------------------------------- ----------------------------------
2020-01-17 17:43:55.5596303 +01:00 2020-01-17 11:43:55.5596303 -05:00

Related

Rails: Converting created_at to PST

I want to convert the created_at to this format January 12, 2:00 PM PST.
The first step I tried was to convert the created_at field to Pacific Standard Time (PST).
However, I'm stuck - I can't even get past this step.
I've tried these, but neither worked:
Time.parse(self.created_at).in_time_zone('Pacific Time (US & Canada)')
time = Time.parse(self.created_at)
time.in_time_zone('Pacific Time (US & Canada)')
I receive no implicit conversion of ActiveSupport::TimeWithZone into String when I do this.
I based it on these questions:
How do you convert the following time from UTC to EST in Ruby (without Rails)?
How to convert time from UTC to PST in rails
Since it is already a datetime, you should be able to just do this to convert it:
self.created_at.in_time_zone('Pacific Time (US & Canada)')
Don't forget to save the new time zone to the record in the database.
Time.parse() is meant to convert strings into datetime(https://apidock.com/ruby/v2_5_5/Time/parse/class).

Convert particular timezone to UTC timezone

For example my local time_zone is Canada and i am getting date in Chennai timezone. How can I convert the Chennai timezone to UTC?
Using server time
You can call ActiveSupport::TimeWithZone#utc on the result.
Example:
Time.zone.now.utc
Keep in mind that .now is using the server time zone when config.time_zone is set.
When you receive a time
If you are getting the datetime in Chennai timezone it will probably look like this: 2019-11-26T12:20:00.655+05:30
To convert it in different time zone, use:
time = Time.parse("2019-11-26T12:20:00.655+05:30")
pacific_time = time.in_time_zone("Pacific Time (US & Canada)")
# and then UTC if you want
pacific_time.utc

Rails 5: Convert Time.zone (e.g "Pacific Time (US & Canada)" ) into a numbered offset (e.g -0700)

This is an ongoing issue I'm having and I don't know how to work with it.
A user sets their Time.zone when they create an account. In this case "Pacific Time (US & Canada)".
When they create an object and enter in the date and time it comes in the format of a string with no explicit timezone offset like so "05/31/2017 2:00 PM"
Knowing these two things. I would like to convert the inputted time string into a UTC format and save it.
I've tried the following but it's not taking the pacific time into account:
time = Time.strptime("05/31/2017 2:00 PM Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z").utc
=> 2017-05-31 14:00:00 UTC
14:00:00 UTC is 7AM pacific. It should be 21:00:00 as it is currently -0800. I would like to find a method to take timezones into account and save them correctly in UTC format.
It however converts correctly if I give it the exact offset like so:
time = Time.strptime("05/31/2017 2:00 PM -0800", "%m/%d/%Y %H:%M %p %Z").utc
=> 2017-05-31 22:00:00 UTC
This problem is killing me. I would simply like to save all date and times in UTC format so all that a user has to do is set their timezone and view times correctly. Also taking into account DST if applicable.
In Rails you can use ActiveSupport to change a time zone without changing value and convert to utc
#parse time as usual
time = Time.strptime("05/31/2017 2:00 PM", "%m/%d/%Y %H:%M %p")
#convert to utc using timezone that you need
res = ActiveSupport::TimeZone.new('Pacific Time (US & Canada)').local_to_utc(time)
#> 2017-05-31 21:00:00 UTC

Daylight Savings Time ignored using in_time_zone Rails 4

I'm having a frustrating issue that I can't seem to narrow down. I have searched many similar articles but they are not close enough to my issue to resolve. I am trying to pull a time from the database and display it in more than one time zone. My Rails app is using UTC as default. Here is what I'm doing:
On the create action I take the string of time which will be saved in the time column in my DB:
params[:schedule][:start] = "09:00"
Time.zone = "Central Time (US & Canada)"
#schedule.start = Time.zone.parse(params[:schedule][:start])
The above formats the time as it is supposed to:
2016-04-12 09:00:00 -0500
This is saved in the DB as:
2000-01-01 14:00:00
This has no time offset which is fine since I know it's in UTC. The problem happens when I go to display the time:
#schedule.start.in_time_zone("Central Time (US & Canada)")
This returns:
Sat, 01 Jan 2000 08:00:00 CST -06:00
Now, since this is a time column, I don't care about the date. I plan on formatting the value to only show the time. However, it is showing CST when it is currently CDT.
I can't figure out why this is happening. As I said I am not setting the Time Zone anywhere in my application.rb or anywhere else and I only set the Time zone on the create action which should be fine when moving to a new action.
Any help on clarifying this would be awesome!
This seems to be because when the time is stored it is stored with the date in the year 2000-01-01 which seems to be why it is using CST. How can I ignore the date when converting it to a particular timezone or will I need to change the column type to DateTime to get this to work properly?
It is showing CST simply because the time is read from the database including the stored date, i.e. it's read as 09:00 of Jan 1st 2000.
I guess you'd have to parse the time upon reading the attribute back. You can use a helper method in your model, for example:
# schedule model
def start_in_zone(zone)
self.start.strftime("%H:%M").in_time_zone(zone)
end
This will take only the hours and minutes part of the stored time and parse it in the given time zone with the date set to today. See this example:
"Sat, 01 Jan 2000 08:00:00".to_time.
strftime("%H:%M").
in_time_zone("Central Time (US & Canada)")
# => Tue, 12 Apr 2016 08:00:00 CDT -05:00
The fact that it matters whether it's CST or CDT means you do, on some level, care about the date. While I'm not familiar with the exact rules of Daylight Savings in that region, I do know that Jan 1 is the middle of winter and will definitely not be on Daylight Savings time.
Add the relevant date into your #schedule before putting it into a time zone, and it should fix the problem.

Why doesn't `config.time_zone` seem to do anything?

In application.rb, it says:
Set Time.zone default to the specified zone and make Active Record
auto-convert to this zone.
Run "rake -D time" for a list of tasks for finding time zone names.
Default is UTC.
But setting config.time_zone = 'Central Time (US & Canada)' or config.time_zone = 'Eastern Time (US & Canada)' has no effect - the created_at field in a model is stil being saved in UTC.
According to this railsforum answer:
config.time_zone just lets rails know
that your server is set to this
timezone so when it writes dates to
the database it can properly convert
it to UTC.
If that is true, then why is it that when my system time is Pacific Time (US & Canada) and config.time_zone = 'Central Time (US & Canada)' or config.time_zone = 'Eastern Time (US & Canada)', that the created_at time is the correct UTC? Should it not be incorrect?!
Because, if the PST time is 8 PM, then EST is 11 PM and UTC is 4 AM.
Presuming that Rails does Time.now, that would be 8 PM. And we told Rails that the server is in EST. So, 8 PM would be EST time as far as Rails is concerned and the UTC would then be 5 AM UTC, which would be incorrect (because the actual time is 8 PM PST/11 PM EST, which is 4 AM UTC)
What's going on here?
Here's a list of concepts and things that may help you:
config.time_zone doesn't set "Server Time", that is controlled by your operating system usually.
Rails always stores your dates in UTC in the database (unless you change a different setting).
Time.now returns the localtime for your computer in your timezone and it also includes the local timezone offset from your operating system, which means Ruby and therefore Rails knows how to convert localtime into UTC. You can try this by using irb directly, so no Rails libraries are loaded:
ctcherry$ irb
>> Time.now
=> Mon Feb 21 20:53:14 -0800 2011
>>
If config.time_zone, or Time.zone is set, to lets say EST, Rails expects that if you set a datetime attribute that you mean for that time and date to be in specified timezone, in this case EST. This is why you set Time.zone equal to your end users timezone, so they can use their local time and dates, and you can pass them directly into your ActiveRecord models and Rails can convert it to UTC for storage in the database.
Does that help at all?
You need to use in_time_zone (i.e. Time.now.in_time_zone) to get some something other than UTC.

Resources