I've been trying to find detailed Arel documentation, but in vain. Finally I tried digging into the source code and figured ou
The following works (note the to_sql in the end):
Arel::Nodes::NamedFunction.new('to_char', Audit.arel_table[:created_at], 'dd-mm-yyyy').to_sql
And, the following works:
tzdate = Arel::Nodes::InfixOperation.new('at time zone', Arel::Nodes::InfixOperation.new('at time zone', Audits.arel_table[:created_at], 'gmt'), Time.zone.tzinfo.name)
The following, does NOT work (note the to_sql in the end) due to TypeError: Cannot visit Arel::Nodes::InfixOperation:
Arel::Nodes::NamedFunction.new('to_char', [tzdate, 'dd-mm-yyyy']).to_sql
Can anyone tell me what is happening here?
There are two issues here:
You need to wrap the date format string with Arel.new('dd-mm-yyyy') (which produces an Arel::Nodes::SqlLiteral).
The time zone strings need to be quoted (e.g. Arel::Nodes::Quoted.new('UTC')). See https://github.com/rails/arel/issues/323
Related
I am trying to create a data field using Mockaroo and they say they have Ruby support but I know nothing about Ruby so I am trying to find out how to do a field that will randomly choose between the 3 options.
now() or
now()+days(-1) or
now()+days(-2) or
now()+days(-3)
Idea 1
I was initially thinking something using random like now()+days(this.rand(-3))
Idea 2
I also thought of using or logic like now() or now()+days(-3) or etc...
This answer may end up being different than a typical ruby solution since Mockaroo has their own little API to use too... Appreciate any help that can be given.
Turns out I had to use the random function first and pass in min and max date parameters.
random(now()+days(2), now()+days(-3))
I'm trying to use a relatively basic IF function but having no luck - i'm sure i just have brackets or parenthesis wrong or something. Reckon it will be childsplay for you guys....
The formula is intended to show how many days a date has passed by. Date is shown in T column.
Basically it was working fine as the following, both for pending and past dates:
=IF(T7<=TODAY(), (TODAY()-T7),-(T7-TODAY()))
But I got greedy and wanted it to return more of a statement when the date has passed, as to how much it has passed by. So I've tried to make this happen with:
=IF(T7<=TODAY(),"EffOut(TODAY()-T7) days ago",-(T7-TODAY()))
Hoping it would enter "EffOut 8 days ago" (when TODAY()-T7 is 8 days) for example.
But it doesnt - it shows the entire argument i.e "EffOut(TODAY()-T7) days ago" in the return cell.
Is it possible to have a kind of embedded formula in the 'value_if' fields, mixed with text in this sense?
Happy to share the document if that would help, but will need to clear the data first so just let me know.
Thanks in advance, any help is much appreciated! Having read other posts I think it will just be a simple fix but its well beyond me! (I only got this far by perusing forums...)
Maybe something like this...
=IF(T7<=TODAY(),"EffOut "&DAYS(TODAY(),T7)&" days ago",-(T7-TODAY()))
=IF(T7<=TODAY(),"EffOut "&(TODAY()-T7)&" days ago",-(T7-TODAY()))
You just need to be careful to put "" around any strings. This is how Excel knows that's not a part of the formula. Remember to out the spaces is to the string like I did above so it looks like a sentence. The & sign combines the results of the calculated parts and the strings.
So I am working through a tutorial building an event manager program and I'm a bit stuck. I want to build a method that will take registration data from a .csv file and then extract the hour times when people registered. However I'm having trouble getting it to work. Here's what I have so far:
def reg_hour(regtime)
regtime = DateTime.new
DateTime.strptime(regtime, "%H")
end
When I run the code though I get this error:
`block in _strptime_i': undefined method `sub!' for #<DateTime: -4712-01-01T00:00:00+00:00 (-1/2,0,2299161)> (NoMethodError)
I am quite confused and any help would be greatly appreciated.
Here's the link to the tutorial if anyone is interested.
http://tutorials.jumpstartlab.com/projects/eventmanager.html
Not sure what you're doing with the DateTime.new and overriding the regtime variable (I'm new to ruby myself). If the regtime is coming out of a csv file, it's probably coming out as a string. Perhaps you could use a regular expression as long as the regdate format is consistent.
If regdate is: "11/12/08 10:47"
Then using:
regdate.scan(/\s\d+:/)
Would return [" 10:"]. Perhaps then you could store that in a array variable and clean it up by removing white space and the colon. There's probably a more elegant solution, but that's my newbie brute force way.
I am not quite sure I fully understand your intentions, but here it is rewritten:
require 'time'
def reg_hour(regtime)
DateTime.strptime(regtime, "%H")
end
d = reg_hour("21/03/2011 14:39:11.642")
puts d.year
Is this something you're trying to do?
I have a string like 2012-01-01T01:02:03.456 that I am storing in a Postgres database TIMESTAMP using ActiveRecord.
Unfortunately, Ruby seems to chop off the milliseconds:
ruby-1.9.3-rc1 :078 > '2012-12-31T01:01:01.232323+3'.to_datetime
=> Mon, 31 Dec 2012 01:01:01 +0300
Postgrs supports microsecond resolution. How can I get my timestamp to be saved accordingly? I need at least millisecond resolution.
(PS Yes I could hack in a milliseconds integer column in postgres; that kind of defeats the whole purpose of ActiveRecord.)
UPDATE:
The very helpful responses showed that Ruby's DateTime is not chopping off milliseconds; using #to_f shows it. But, doing:
m.happened_at = '2012-01-01T00:00:00.32323'.to_datetime
m.save!
m.reload
m.happened_at.to_f
Does drop the milliseconds.
Now, the interesting thing is that created_at does show milliseconds, both in Rails and Postgres. But other timestamps fields (like happened_at above) don't. (Perhaps Rails uses a NOW() function for created_at as opposed to passing in a DateTime).
Which leads to my ultimate question:
How can I get ActiveRecord to preserve millisecond resolution on timestamp fields?
ActiveRecord should preserve the full precision from the database, you're just not looking at it properly. Use strftime and the %N format to see the fractional seconds. For example, psql says this:
=> select created_at from models where id = 1;
created_at
----------------------------
2012-02-07 07:36:20.949641
(1 row)
and ActiveRecord says this:
> Model.find(1).created_at.strftime('%Y-%m-%d %H:%M:%S.%N')
=> "2012-02-07 07:36:20.949641000"
So everything is there, you just need to know how to see it.
Also note that ActiveRecord will probably give you ActiveSupport::TimeWithZone objects rather than DateTime objects but DateTime preserves everything too:
> '2012-12-31T01:01:01.232323+3'.to_datetime.strftime('%Y-%m-%d %H:%M:%S.%N')
=> "2012-12-31 01:01:01.232323000"
Have a look at connection_adapters/column.rb in the ActiveRecord source and check what the string_to_time method does. Your string would go down the fallback_string_to_time path and that preserves fractional seconds as near as I can tell. Something strange could be going on elsewhere, I wouldn't be surprised given the strange things I've seen in the Rails source, especially the database side of things. I'd try converting the strings to objects by hand so that ActiveRecord will keeps its hands off them.
Changing m.happened_at = '2012-01-01T00:00:00.32323'.to_datetime in the code above to m.happened_at = '2012-01-01T00:00:00.32323' solves the problem, though I have no idea why.
I ended up here when I was suffering from using the RVM provided binary Ruby 2.0.0-p247 on OS X (Mavericks) which was causing rounding to whole values of seconds when retrieving times from Postgres. Rebuilding Ruby myself (rvm reinstall 2.0.0 --disable-binary) solved the issue for me.
See https://github.com/wayneeseguin/rvm/issues/2189 which I found via https://github.com/rails/rails/issues/12422.
I recognise that this is not THE answer to this issue but I hope this note might help someone struggling with it.
to_datetime does not destroy millisecond resolution of data - it's simply hidden because DateTime#to_s doesn't display it.
[1] pry(main)> '2012-12-31T01:01:01.232323+3'.to_datetime
=> Mon, 31 Dec 2012 01:01:01 +0300
[2] pry(main)> '2012-12-31T01:01:01.232323+3'.to_datetime.to_f
=> 1356904861.232323
That said, I suspect that ActiveRecord is mistakenly hiding that information when persisting the data; remember that it is database-agnostic, so it takes approaches that are guaranteed to work across all of its database targets. While Postgres supposed microsecond information in timestamps, MySQL does not, so I suspect AR selects for the lowest common denominator. I couldn't be sure without getting into the guts of AR. You may need a Postgres-specific monkeypatch to enable this behavior.
I have a column called Start Time (it's a SharePoint Default Calendar Column). I need to validate if the Start Time is less than today or not? Without using javascript? Is this possible?
I have tried this:
Created a column called Today type as Date and Time.
Default value is current date.
Then compared the Start Time and Today in validation settings like the following:
=[Start Time] < [Today]
it seems not working. help please?
Try this code instead of yours
=[Start Time]<NOW()
I use this to validate that Start Date must be less than or equal to Today:
=[Start Date]<=Today()
...and it works for me.