Select approriate cell based on current time - google-sheets

Have been scratching my head for the last hour now.
I have a timetable with time values in Column A and then activity on Column B
e.g.
COLUMN A | COLUMN B
0.3333333333 EAT
0.3715277778 SLEEP
0.4097222222 PRAY
0.4444444444 DO NOTHING
0.46875 .
0.5034722222 .
0.5416666667 .
0.5798611111
0.625
0.6666666667
What I want to do is excel to tell me what I should be doing now, and what I should be doing next.
I can get the current time like this: =MOD(NOW(),1)
I'm thinking I need to turn the value of =MOD(NOW(),1) into exactly one of the values in column A, then I can do a VLOOKUP to tell me what I need to be doing now/next (in Column B)
I've been playing with MATCH, CHOOSE, I have to use some nested AND to find out if the current time is before or after the times in Column A. But I just can't figure this one out.
Many thanks.

Well, you can do it with a few simple steps.
First, as I understand in column A you have start time, then in column B you need end time, in cell B2 put =A3.
So you can have something like:
start end to-do
08:00:00 08:55:00 eat
08:55:00 09:50:00 go
09:50:00 10:40:00 something
10:40:00 11:15:00 .
11:15:00 12:05:00 .
12:05:00 13:00:00
13:00:00 13:55:00
13:55:00 15:00:00
15:00:00 16:00:00
16:00:00
It's very easy from there.
Add one column on your left (for vlookup purpose). Let's say you have current time in cell G2. Then in your new column A in cell A2 put a formula:
=AND($G$2>=B2;$G$2<C2)
to check if your current time is in the time range you have in your start and end.
If your current time is 11:45 then you should have something like this:
start end to-do
FALSE 08:00:00 08:55:00 eat
FALSE 08:55:00 09:50:00 go
FALSE 09:50:00 10:40:00 something
FALSE 10:40:00 11:15:00 .
TRUE 11:15:00 12:05:00 .
FALSE 12:05:00 13:00:00
FALSE 13:00:00 13:55:00
FALSE 13:55:00 15:00:00
FALSE 15:00:00 16:00:00
FALSE 16:00:00
then all you need to do is vlookup where TURE is.
EDIT: to check what you should do next you need vlookup nested in vlookup. First instead using vlookup to find what value is in column to-do you need to vlookup value in the column end (12:05:00). Then this value can be set as value to look up in range columns start:to-do.

Related

Get max change between rows, ignoring empty cells at end of list

I have a spreadsheet where I'm tracking my net worth over time. Once a month, I add in my account balances.
In one sheet, I have this structure:
Date
Year
Net Worth
Account1
Account2
Account3
Jan 31, 2021
2021
$320
$200
$140
-$20
Feb 28, 2021
2021
$340
$200
$150
-$10
Mar 31, 2021
2021
$410
$250
$200
-$40
Apr 30, 2021
May 31, 2021
...rest of months for the year
The formula in the Year column is =if(C3<>"", year(A3), "").
The formula in the Net worth column is =if(sum(D3:F3)<>0, sum(D3:F3), "").
The Problem:
I'd like to have a cell which lists the greatest 1 month change (so $410 - $340 = $70), without having to update the formula every month. (In an ideal world, I never need to touch it again, only ever having to enter account balances once a month.)
What I've got so far:
=if(
abs(min(ArrayFormula(C3:C400 - C2:C399)))=max(ArrayFormula(abs(C3:C400 - C2:C399))),
min(ArrayFormula(C3:C400 - C2:C399)),
max(ArrayFormula(C3:C400 - C2:C399))
)
However, this includes the change from $410 to "", which is coerced to $0. So instead of the expected $70, I'm instead getting $410.
How can I get the greatest 1 month change, but ignore the empty string values?
Easiest way to fix it is just to put in an if clause I think:
=ArrayFormula(max(if(C3:C400<>"",abs(C3:C400-C2:C399),)))
because Max will ignore the empty string generated by the If statement
or slightly shorter:
=ArrayFormula(max((C3:C400<>"")*abs(C3:C400-C2:C399)))
so that the change for any empty cells is set to zero.
These assume that C2 itself is not blank!

Year query returns no results

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'")

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.

Format time to show day and month

For a project I am working on I receive date and time in this format:
2015-08-16 15:00:00 UTC
yyyy-mm-dd hh-mm-ss UTC
How can I make the time display as "Saturday, August 16th 2015 at 3:30PM"? ("15:00" would be fine as well.)
And how would I make it so it checks if the date has already passed or not, so that it only displays dates that have not passed?
How would I make it so I can so that the time display as "Saturday, August 16th 2015 at 3:30PM (15:00 would be fine as well)?
Time.parse('2015-10-20 15:23 UTC').strftime('%A, %B %dth %Y at %l:%M%p')
#=> "Tuesday, October 20th 2015 at 3:23PM"
You might have to tweak it a bit to fix the suffixes (1st, 2nd, 3rd, etc)
And how would I make it so it checks if the date has already pasted or not?
You could do it like this (I'm sure there's a simpler way):
EDIT: Yes, there is a much simpler way -- check Matt's answer.
require 'time'
if Time.parse(my_date).to_i - Time.now.to_i > 0
# my_date is in the future.
end
To start, convert your string to a Time object via Time.parse(string) (APIDock).
After that you have all of the Time class to play with.
time.strftime
time.past?

Rails: how to create Time object in specific time zone

My app is working in "Moscow" (+04:00) timezone. But sometimes I need to create time object by only local time (for example "01 may 2012 13:45") and name of ActiveSupport::TimeZone object (for example "Berlin": +02:00 in Summer Time and +01:00 otherwise).
For example if I get "01 may 2012 13:45" and "Berlin" as input I want to yield "2012-05-01 13:45:00 +0200" or "2012-05-01 11:45:00 +0000". I create following function:
def from_local_datetime(local_datetime, time_zone)
offset = Time.now.in_time_zone(time_zone).formatted_offset
datetime = case local_datetime
when String
DateTime.parse(local_datetime)
else
DateTime.new(local_datetime)
end.change(:offset => offset)
return datetime
end
And at the first look it works as I expected. But is it a best practice for this kind of task? May be in some situation It works with errors. I'm not definitely sure.
I would be greatful to any comments.
UPD: I think bug may occur about time when DST changing the time. For example 26 march 2011 was GMT+1 in Berlin time zone and Time.now.in_time_zone("Berlin").formatted_offset returns "GMT+1", but it would be GMT+2 in 27 march 2011. So if I call from_local_datetime("28 march 2011", "Berlin") before 27 march it returns 28 march 2011 00:00:00 +0100, but If I call it after changing the time my function returns 28 march 2011 00:00:00 +0200 :(
Your conversion method is the right approach.
With web sites, you should make sure times are stored as UTC in the database. If you can get the UTC value out of the database, instead of the local time (or maybe you can set your web server's time zone to UTC) it won't have to convert the time from UTC to local time, when you are going to then convert it to the user's timezone anyway.
And, of course, you will have to store the user's time zone preference.
TZInfo::Timezone.get('Europe/London')
Find the time zone
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

Resources