I'm building a schedule in rails and I need to see if today's date matches the date of an event in the future. I have an event model with a date field and I know the dates of all the future events, but how do I add those dates to the table in a way rails will understand?
I'd like to do something like:
if Time.now is equal to next event
# do this
Time.now outputs
2014-03-18 11:05:14 -0500
How do I add that sort of format to the dates in the table so that I can compare Time.now to the date of the future event?
EDIT
Say I'm creating a new Event in the rails console, And I want the date of the Event to be April 1, 2014. I'm trying to figure out what syntax I need to enter the date in the console. For example, to create an Event in console I would do something like
Event.create(name: "Event1", date: ??)
What do I put in place of the question marks for the date of April 1, 2014 in syntax understood by the computer? I need April 1, 2014 in a datetime format, not a string.
Thank you!
seeds.rb is—as the file extension implies—just Ruby.
You can supply the date in any form that an available Ruby library can parse into a Time or Date object.
If you want to keep it human-readable, you can use Date.parse:
Event.create(name: 'Event1', date: Date.parse('Apr 1 2014'))
Event.create(name: 'Event2', date: Date.parse('April 1, 2014'))
Event.create(name: 'Event3', date: Date.parse('1-Apr-14'))
Or, if you need human-readable times as well, Time.parse:
Event.create(name: 'Event4', date: Time.parse('09:15 1 Apr 2014'))
Event.create(name: 'Event5', date: Time.parse('April 1, 2014, 9:15am'))
Event.create(name: 'Event6', date: Time.parse('1-Apr-14, 09:15 -0700'))
If you prefer to use UNIX timestamps, Time.at creates a new Time object from them (and offers a mild performance benefit over parsing textual dates):
Event.create(name: 'Event7', date: Time.at(1395166977))
If you have defined next_event as a datetime column in database, rails will automatically initialize it as a date_time object when you load it from database. All you need is this
if Time.now.to_date == next_event.to_date
For adding the future days, you can use days.from_now method
For eg
1.days.from_now #Wed, 19 Mar 2014 16:29:26 UTC +00:00
2.days_from_now #Thu, 20 Mar 2014 16:30:16 UTC +00:00
Or you can use normal addition
Time.now + 2.days
Time.now + 2.hours
Time.now + 10.minutes
Event.create(name: "Event1", date: (Time.now + 1.day))
Related
I'm trying to compare date that comes from ActionMailbox mail.date with a date field in my PostgreSQL DB Table to check if a post for the same date already exists. The dates comes in different format I guess, how canI format them in same way to compare? The time section is irrelevant.
Date format that comes from email as below I guess. Looking at the Logs on server
Date: Wed, 24 Mar 2021 09:57:57 +0000
Date format I have in the DB is as below. Output of Post.last in rails c
date: "2021-03-24 09:57:57.000000000 +0000
I need to check if dates matches or not?
Btw the interesting thing is, I can just save mail.date to db without any particular formatting, I guess it is formatting itself before saving.
Date format I have in the DB is as below.
Databases don't store timestamps nor dates as strings, they're stored as numbers. The string format is just for humans. Unless you're storing the date as a string.
I'm trying to compare date that comes from ActionMailbox mail.date with a date field in my PostgreSQL DB Table to check if a post for the same date already exists.
Those are standard date formats, RFC 2822 and ISO 8601. So long as your date column has a date type you don't need to convert them. Rails or Postgres will take care of the conversion.
Thing.where(date: mail.date)
However, your "date" field is storing a timestamp. It might be misnamed, or it might be mistyped. If you only want to store the date, use t.date in your migration.
If you did, you'd parse them into Time objects, then compare.
t1 = Time.zone.parse("Wed, 24 Mar 2021 09:57:57 +0000")
t2 = Time.zone.parse("2021-03-24 09:57:57.000000000 +0000")
p t1 == t2
Btw the interesting thing is, I can just save mail.date to db without any particular formatting, I guess it is formatting itself before saving.
Rails type conversion is parsing the String into an ActiveSupport::TimeWithZone object.
> thing = Thing.new
> thing.created_at = "Wed, 24 Mar 2021 09:57:57 +0000"
> thing.created_at
=> Wed, 24 Mar 2021 04:57:57.000000000 CDT -05:00
> thing.created_at.class
=> ActiveSupport::TimeWithZone
I have a Holiday model, with a holiday_date attribute of DateTime.
I added a new Holiday (New Years Day) with a date of 1/1/2019.
When I do in the console Holiday.last, I see this:
#<Holiday id: 50, name: "New Years Day", holiday_date: "2018-12-31 23:00:00", created_at: "2018-11-13 13:15:54", updated_at: "2018-11-13 13:15:54">
So it is saved in UTC time, a day earlier. When I then do Holiday.last.holiday_date I get this:
Tue, 01 Jan 2019 00:00:00 CET +01:00
Great, the date is converted to our CET date and time. But when I query for a year like this:
Holiday.where("extract(year from holiday_date) = '2019'")
It returns no results. So it seems that there is no conversion to CET time with this query. How can I make sure that the query returns the holiday I added?
You'll have to cast timezones twice:
Holiday.where(
"extract(year from holiday_date AT TIME ZONE 'UTC' AT TIME ZONE 'CET') = '2019'"
)
This will work, but it would be nice to use indices for your query, we'll just have to prepare it better:
year = Time.zone.parse("2019-01-01")
Holiday.where("holiday_date BETWEEN ? AND ?", year.beginning_of_year, year.end_of_year)
# SELECT "holidays".* FROM "holidays" WHERE (holiday_date BETWEEN '2018-12-31 23:00:00' AND '2019-12-31 22:59:59.999999')
I would really think whether you need datetimes for your holiday_date column, perhaps dates would be enough, so that you don't have to deal with timezones.
You can query by timezone like this
Holiday.where("extract(year from holiday_date AT TIME ZONE 'CET') = '2019'")
I know I can create Date.tomorrow and there are options like midnight, at_noon etc. I need a more specific time than this.
Specifically, I am looking to create a DateTime that is tomorrow at 11am. I don't see anything in the DateTime docs. Is there any simple way to accomplish this? Thanks!
In Rails you would probably use tomorrow, in_time_zone and change:
Date.tomorrow.in_time_zone.change(hour: 11)
#=> Sat, 08 Aug 2015 11:00:00 CEST +02:00
This returns a ActiveSupport::TimeWithZone instance, just like midnight, at_noon etc.
Pure Ruby:
(Date.today + 1).to_datetime + Rational(11, 24)
or equivalently,
Date.today.to_datetime + Rational(35, 24)
I want to orders which are confirmed particular day.
This is particular day:
today = Time.zone.now
Wed, 10 Jun 2015 13:31:16 IST +05:30
This is range of particular day
value = today.beginning_of_day()..today.end_of_day()
Wed, 10 Jun 2015 00:00:00 IST +05:30..Wed, 10 Jun 2015 23:59:59 IST +05:30
But when I execute this, SQL query date range is changed,
orders = Order.where(confirmed_at: value)
SELECT "orders".* FROM "orders" WHERE "orders"."confirmed_at" BETWEEN '2015-06-09 18:30:00.000000' AND '2015-06-10 18:29:59.999999' ORDER BY orders.confirmed_at DESC
In this orders confiremed between '2015-06-09 18:30:00.000000' AND '2015-06-10 18:29:59.999999'
But I wants confirmed between 'Wed, 10 Jun 2015 00:00:00 IST +05:30..Wed, 10 Jun 2015 23:59:59 IST +05:30'
You can use Time.zone.now.to_time for today.
today = Time.zone.now.to_time
value = today.beginning_of_day()..today.end_of_day()
I hope this helps.
Which DB are you using?
ActiveRecord will declare time columns using data types that do not support timezones. For example, in Postgres it will use timestamp without time zone.
This means that all Time, DateTime and TimeWithZone values set on an ActiveRecord object will be written to the DB as UTC.
Rails will then take care to apply and remove the right offsets each time the values are read or written, using the current value of Time.zone (e.g. for the current web request).
Just check the docs for TimeWithZone and think about what should go in your WHERE clause.
It probably depends on the specific context, but you might have to use UTC values in your query.
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.