Time.parse .. the hour is not what is expected - ruby

Why does this say 13 instead of 14?
Time.parse('2014-01-08 14:01:00 +0300').hour
# => 13

The time is parsed correctly, but displayed in your local time zone.
This happens in my console:
Time.parse('2014-01-08 14:01:00 +0300')
=> 2014-01-08 12:01:00 +0100
Note the +0100.

http://apidock.com/rails/Time/use_zone/class
should help you to get time in correct time zone
Time.use_zone(zone name) accepts block. Inside this block application uses time zone you've provided in zone name
use_zone(time_zone) public
Allows override of Time.zone locally inside supplied block; resets Time.zone to existing value when done.

Related

Laravel - Carbon giving wrong time when using shiftTimeZone and setTimeZone

Laravel carbon is returning time in UTC when printing Carbon::now() but doesn't give the correct time while using shiftTimezone and setTimezone
Below are the results:
Carbon::now(); //"2021-07-20T07:30:29.775871Z"
Carbon::now()->timezoneName; //UTC
Carbon::now()->shiftTimezone('Asia/Kolkata'); //"2021-07-20T02:00:29.452997Z"
Carbon::now()->shiftTimezone('+05:30'); //"2021-07-20T02:00:29.452997Z"
Carbon::now()->shiftTimezone('Asia/Kolkata'); //"2021-07-20T07:30:29.775871Z"
In case of shiftTimeZone, it should add 05:30 hours to the time. But what it actually does is reduces 05:30 from the UTC time.
And for setTimezone it is taking the same time as UTC.
Any idea where I'm getting it wrong?
In my application, I never use shiftTimezone or setTimezone.
I always go with something like the following:
Carbon::now()->timezone('Asia/Kolkata');
It returns me the date in Asia/Kolkata timezone, without any issue.
What you put in comments here is not the content of the instance, it's an UTC ISO-8601 string as it's converted to be rendered in JSON output for instance:
echo Carbon::now()->format('Y-m-d H:i:s.u p'); // 2021-07-20 09:36:08.596951 Z
echo Carbon::now()->shiftTimezone('Asia/Kolkata')->format('Y-m-d H:i:s.u p'); // 2021-07-20 09:36:08.596951 +05:30
echo Carbon::now()->shiftTimezone('+05:30')->format('Y-m-d H:i:s.u p'); // 2021-07-20 09:36:08.596951 +05:30
echo Carbon::now()->shiftTimezone('Asia/Kolkata')->format('Y-m-d H:i:s.u p'); // 2021-07-20 09:36:08.596951 +05:30
JSON is converted to UTC because it's a standard way to exchange datetime information, timezone should be a separated information and you only need it to force a timezone, but 99% you want the user/client/browser to use its own timezone so new Date('2021-07-20T09:36:08.596951Z') in JavaScript or equivalent in other languages will work just fine and apply the current device timezone, which is the correct way for proper localization. Very specific cases where you want to display a date in a timezone that IS NOT the user device timezone, then you should pass "Asia/Kolkata" explicitly in your JSON output.

Does anyone know what TimezoneOffset does on LuisPredictionOptions?

I'm sending LUIS a query that is based on a time value (e.g. "what is the time 10 minutes from now" - just an example). I want the time to come back in the local timezone, so on the LuisPredictionOptions object (C#) I set the TimezoneOffset (as an example I set it to 2 hours ahead, or 120 minutes).
In Fiddler I can see when it calls the LUIS endpoint it's correctly adding "timezoneOffset=120.0".
However, the timezone comes back as UTC - it doesn't matter whether the timezoneOffset is set, or even what it is set to, the time always comes back UTC, using the builtin datetimeV2 entity.
Does anyone know what the TimezoneOffset property is for? Am I just using it incorrectly? Is there another way perhaps to get a local time from LUIS?
[Update]: Here are some examples: https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/[AppId]?verbose=true&timezoneOffset=0&subscription-key=[subscriptionkey]&q=/luis/v2.0/apps/c1be57f4-3850-489e-8266-db376b82c011?timezoneOffset=120&log=true
https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/[AppId]?verbose=true&timezoneOffset=0&subscription-key=[subscriptionkey]&q=/luis/v2.0/apps/c1be57f4-3850-489e-8266-db376b82c011?timezoneOffset=240&log=true
and I'm trying the following example utterance: "in 10 minutes".
When I do this, the timex is in UTC (e.g. timex=2020-01-11T16:08:25) and the "value" comes back with the same value, minus the "T", as follows: value=2020-01-11 16:08:25
I could understand perhaps if the timex is in UTC, but then possibly "value" should be adjusted by the timezoneOffset?
It looks like there's an incorrect question mark in your URL, right before timezoneOffset.
Using the same query I was able to get the expected behavior, where the returned value is different by 10 minutes.
Which SDK are you using? Perhaps you're using the V3 Runtime SDK which uses the V3 endpoint that doesn't use timeZoneOffset but instead uses datetimeReference, and need to use the V2 Runtime SDK instead.
https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/[app-id]?verbose=true&timezoneOffset=10&subscription-key=[key]&q=in 10 minutes
The TimeZoneInfo class's FindSystemTimeZoneById method can be used to determine the correct timezoneOffset based on system time. An example in C# is shown below:
// Get CST zone id
TimeZoneInfo targetZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
// Get local machine's value of Now
DateTime utcDatetime = DateTime.UtcNow;
// Get Central Standard Time value of Now
DateTime cstDatetime = TimeZoneInfo.ConvertTimeFromUtc(utcDatetime, targetZone);
// Find timezoneOffset
int timezoneOffset = (int)((cstDatetime - utcDatetime).TotalMinutes);
Reference:
https://learn.microsoft.com/en-us/azure/cognitive-services/luis/luis-concept-data-alteration?tabs=V2#c-code-determines-correct-value-of-timezoneoffset

Scope to query last year's data

I've written a scope that returns all objects with a transfer_date from the beginning of the current year to the end of the current year.
scope :year, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year, Time.zone.now.end_of_year) }
This works well and gives me the objects that I need. But now I'm looking to write a scope that does the same thing but for the previous year. I know there's no method in the Time class for beginning_of_last_year so I'm thinking that it might be better to define a class method instead of a scope.
If I wanted to return all objects with a date between the beginning of last year and the end of last year, what would be the best way to express this in Ruby?
I've written this as a scope but I think it can be cleaner:
scope :previous_year, lambda {where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year - 1.year, Time.zone.now.end_of_year - 1.year)}
There are a few optimizations I'd make here.
Since you already have ActiveSupport loaded and you're using it, make use of the ago method, and write something that's a little more flexible. You can also use a range and ActiveRecord can handle writing the appropriate query for your DB, no string substitution needed.
scope :from_year, ->(date) { where(transfer_date: date.beginning_of_year..date.end_of_year) }
# usage
Record.from_year(1.year.ago)
This is a lot less rigid. You can now easily query for records that are from 5 years ago without writing any new code. If you find yourself using last year in a lot of places, make it a convenience method:
def self.last_year
from_year 1.year.ago
end
How about this:
(Time.zone.now - 1.year).beginning_of_year
(Time.zone.now - 1.year).end_of_year
I use this line of code
scope :last_year, lambda {where(transfer_date: 1.year.ago.all_year)}
irb(main):032:0> 1.year.ago.all_year
=> Thu, 01 Jan 2015 00:00:00 UTC +00:00..Thu, 31 Dec 2015 23:59:59 UTC +00:00

Why can't I modify a frozen Time in Twitter gem?

I have a Tweet object from the twitter gem, called #tweet.
I am able to do:
#tweet.created_at --> `#tweet.created_at.class` outputs `Time`
However, I want to change the timezone of created_at, so I tried:
#tweet.created_at.utc
And got:
can't modify frozen Time
How would I change from UTC−08:00 that my current created_at is, to CET time?
Since the created_at time field of the tweet has been frozen, you can't modify it, so utc will raise the Exception, because it tries to change value of self. Instead of modification you shell to duplicate the variable and reassign it:
#tweet.created_at = #tweet.created_at.dup.utc

Rails change default timezone

I'm trying to change default timezone in Rails 3.2.8 app to GMT+04:00, but I don't know how to do it. The following solutions do not work for me:
config.time_zone = 'Moscow'
config.time_zone = "(GMT+04:00) Moscow"
config.active_record.default_timezone = 'Moscow'
config.active_record.default_timezone = :local
Also I've tried in rails console the following:
ActiveSupport::TimeZone.all.map(&:name)
which returned a list of values, including "Moscow".
Time.zone returned (GMT+00:00) UTC which is not correct, it should be (GMT+04:00) UTC. Then I changed Time.zone = "Moscow" and Time.now returned the correct value (... +0400).
So to fix it I simply used Time.now + 4.hour, but I also need datetime_select to display my local time. Time.now + 4.hour is not a correct solution.
How one can set default time zone to their local value?
All of a sudden I've localized the problem.
I run Win7 and my WEBrick server is showing the correct time, but the project itself shows a wrong one. In the same time, my production server is working correctly, so, obviously, the problem is with the OS.
UPD: The problem is fixed. I should have restarted the WEBrick server after changing the application.rb file.

Resources