Rails cant save correct date into database - ruby-on-rails

I have a date format like this "18/12/15" as input (it is a string)
18 => day
12 => month
15 => year (2015)
I am trying to store it in my db in a date column but it doesnt save the proper date (for the previous exemple I get Sat, 15 Dec 2018 whereas I should get something like day, 18 Dec 2015.)
How can I fix that

You could use strptime:
require 'date'
Date.strptime('18/12/15', '%d/%m/%y')
#<Date: 2015-12-18 ((2457375j,0s,0n),+0s,2299161j)>

You want to define a date with the order of day, month, year, while, due to the locale your intention is interpreted as year, month, day.
You can do one of the following:
pass the parameters in inverted order
implement a method which gets the parameters in the correct order and inverts them
set the locale to the one you intend to use
use strptime, as spickermann described

Related

Validate Date String

We have a new field being added to our app where the client wants to be able to put in Sept 22. The input will be part of an import with 100 or so records. I know there are many libraries for parsing it but we want to be able to validate it. In case someone were to make a typo. Any thoughts or libraries to do this?
DateTime.parse will parse "Sept 22" with current year.
you can just make a dateTime with specified year as
date = DateTime.parse("Sept 22")
date_time_with_year = DateTime.new(year, date.month, date.day)
Check out Chronic
You can do things like
Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
#=> Sat May 27 12:00:00 PDT 2000
It will attempt to guess what the string was trying to convey, by default (ie: "Sept 27" will actually parse to something like 2013-09-27 12:00:00 -0500

Time in string format to using strftime

I am trying to change a time of an event I pulled from Facebook which comes in a hash with time as a string. eg:
"fbevents" =>
{
"event1" => "2013-04-27T08:00:00-0400"
"event2" => "2013-04-27"
}
While using method strftime on the time, it won't allow it because it is a string. I want to change it to format:
Day name, Month name, Year, time.
You can parse a string to create a Date. There are two methods that may be of use: parse and _parse. The first one creates a Date, the second one returns a hash of separated date values.
Date.parse "2013-04-27T08:00:00-0400"
=> Sat, 27 Apr 2013
Date._parse "2013-04-27T08:00:00-0400"
=> {:zone=>"-0400", :hour=>8, :min=>0, :sec=>0, :year=>2013, :mon=>4, :mday=>27, :offset=>-14400}
Use the first one if you're just looking to create a new Date instance. Use the second if you want to grab specific parts of the date to do other things with.

How to order data by ONLY Hour:Minute format in MongoDB/Mongoid? (Without date!)

I'm using MongoDB and Mongoid in my project. I have some difficulties with ordering "Time" field data.
As you know, eventhough you set a field type as Time inside your Mongoid Document, time data is stored as this format (note that I use +2 hours offset to get my own timezone's time instead of UTC):
Mon, 31 Dec 2012 08:30:00 EET +02:00
I'm not sure if I'm missing something but this is what happens to me.
I want to use that Time data inside one of my views. I need to sort some related stuff by ONLY Hour:Minute format. I don't want Rails to take care of the DATE part of the field data. Because whenever a new Time record inserted to DB, it takes the day info as CURRENT DAY.
Issue is:
Because of it saves CURRENT DAY for each of new Time records, when I try to order_by("hour DESC") NEW records always retrieved first eventhough HOUR part of the data is bigger!
For example:
First data:
=> Tue, 27 Nov 2012 19:50:00 EET +02:00
Second data:
=> Mon, 24 Dec 2012 18:45:00 EET +02:00
As you know, normally, 19:50 is bigger than 18:45. But in this scenario, because of Rails takes day info into calculation, 18:45 looks like bigger than 19:50!
So what is the work around for this issue?
Thanks in advence.
I've found an answer to this at Mongoid's issues list:
https://github.com/mongoid/mongoid/issues/1169
That's really weired...
If I understood well, Time field type is totally useless! What is the difference between DateTime and Time then??
You even can not compare hours and minutes ONLY inside a Time field.
And hold your breath for the work around...
Solution is:
Not to use Time field type! Just use String and compare hours and dates via that procedure.
Person.where(:time.gt => "13:00")
If some could explain this weired situation, I would be happy.
Best way to store time of day is as seconds_since_midnight in an Integer field. Then you can just sort normally.
field :time, type: Integer
validates :time, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 86399 }
http://api.rubyonrails.org/classes/DateTime.html#method-i-seconds_since_midnight
http://api.rubyonrails.org/classes/Time.html#method-i-seconds_since_midnight

Rails datetime - insert current year when updating date with missing year

On my page I'm using the jquery datetimepicker to get a date and time from the user. When the user selects a datetime, the format of the datetime I get is, for example: "Fri, Sep 21, 1:00PM". I do not get the year since also getting the four digit year makes the whole thing too long for the textbox.
When I pass this date (which is Fri, Sep 21, 1:00PM) back to my controller, and use the update_attributes to update the date in the database, the date that gets inserted is, "0000-09-21 13:00:00.000000". The year becomes 0000 since I was missing the year in the date. I want 2012 obviously. Any ideas how I can achieve this? Please note that I don't want to hardcode 2012 but want it to pick up the current year. Thanks.
Try this
1.9.3p194 :012 > require 'date'
=> true
1.9.3p194 :013 > d= DateTime.parse("Fri, Sep 21, 1:00PM")
=> #<DateTime: 2012-09-21T13:00:00+00:00 ((2456192j,46800s,0n),+0s,2299161j)>
you will get current year.

Rails timestamps don't use the right timezone

I'm a bit confused about timezones in rails. I want my rails app to use British Summer Time (like daylight savings in the US) for the timestamps set in updated_at and created_at in my models. I changed my environment.rb to say
config.time_zone = 'London'
The ubuntu server my app is on seems to use BST for it's time: in the command line, for example, if i type 'date' i get the current time (not offset by an hour). In the rails console, i see the following:
>> time = Time.now
=> Wed Oct 27 16:29:17 +0100 2010
>> time.zone
=> "BST"
All fine. However, if i make a new AR model object and save it, the timestamps are from an hour ago. So, it looks like this is using UTC. Now, i can see the logic in this: since the timestamps might be used in the model logic, you want them to be based on an unvarying yardstick time, ie UTC. But, this is a weird bit of behaviour that i don't understand:
#change a record and save it
>> someobj.save
=> true
#object's updated_at is one hour ago
>> someobj.updated_at
=> Wed, 27 Oct 2010 15:34:22 UTC +00:00
>> Time.now
=> Wed Oct 27 16:34:31 +0100 2010
#however, Time.now - object's updated at is just a few seconds.
>> Time.now - someobj.updated_at
=> 15.305549
So, before doing the subtraction, updated_at is converted into the current time zone.
The reason i want to show the date in the current time zone is just for status reports etc in the views: if someone updates something i want them to see that it was updated '1 minute ago' not 'one hour ago'.
Can anyone unconfuse me? cheers, max
EDIT: My immediate problem, of showing the right time in the status, is solved by using the 'time_ago_in_words' helper, which adjusts for time zone. I'd still like someone to explain what's going on with the timestamps though :)
Timestamps are stored in UTC by default, and this is probably the best way to do it. If you move from one server environment to another, you don't want all of your times shifting around just because you switched time zones.
If you want to know what the timestamp is in your local time zone, you just have to ask for it that way:
someobj.updated_at.localtime
Note the offset listed at the end of the times -- the first offset is 0, the second is 1. When the time calculation occurs, the offset is included automatically, so that the subtraction gives you the correct result. someobj.updated_at and Time.now each displays its value in a different time zone, so they are really only 9 seconds apart, not 1 hour and 9 seconds.

Resources