I'm with a problem doing a part of a program, I hope you can help me.
I have this three columns in excel;
01-01-2012 00:15 A 7,160000
01-01-2012 00:30 A 1,600000
01-01-2012 00:45 C 3,040000
01-01-2012 01:00 A 1,560000
01-01-2012 01:15 A 0,000000
01-01-2012 01:30 D 0,000000
01-01-2012 01:45 A 0,000000
t goes until 31-01-2012 23:45
And now I want to read them into MATLAB and convert them into 3 new matrix with this format;
Timestamp
01-01-2012 00:00
01-01-2012 01:00
(...)
Period
A
A
Price
11,800000
10
So basically I want a program that read's timestamp and keep's day month year and hour (ignoring the minutes), for that period of time it needs to show the most repetitive value in periods of one hour (for example: it will give A to 00 and C to 01) and finally I want it to sum the prices for that hour (so it will sum the price at 00:15 + price at 00:30 etc.)
It will be a huge help, if you can solve me this problem.
P.S In the 1 hour periods I will always have one most repetitive marker (3 of A and 1 C, 3 D and 1 A etc.) I could find in this month 4 markers, A B C D. This markers aren't cyclic but I will find it all across the month.
It seems to me like your main issue is reading the data from Excel and get it in a format you can work with. If so:
Check out xlsread. You have a lot of possibilities there. You can for instance use the following syntax:
[num,txt,raw] = xlsread(___)
but if you are new to MATLAB and don't require the most efficient way, I would recommend you to read each of the columns separately. Note: This is not the best way, but it's the easiest way in my opinion. You can use this command on each of the columns (thus calling it three times):
num = xlsread(filename,sheet,xlRange)
Check out this page to see how you can handle the dates. In summary, convert the dates to numeric values in Excel. Since you have hours and minutes, this will be a decimal number representing the number of days since Jan 01, 1900 (or Jan 02, 1904 if on MAC). Since MATLAB counts from Jan 01, 0000, you need to add some 1900 years after reading the file (check the reference I gave to see how).
One way to handle that you don't want minutes is to convert to datevec, and zero out the last columns (this way you will also remove the information):
[Y, M, D, H, MN, S] = datevec(___) ;
% or
date_vector = datevec(___);
% Where you just don't use the MN and S variables
If you want the dates looking like dates, convert the datevec to datestring. Check out formatOut, and you can choose the format you want.
Try out the above. I'm afraid I can't do that work for you.
To get the most repetitive values, check out mode. mode(X) returns the sample mode of X, which is the most frequently occurring value in X. You can also replicate this functionality by combining some of the following: sort, unique, diff or all. And you can of course use sum to sum the values.
If it's only the last part here your stuck on, I suggest you rephrase the question a bit. If it's both, and you get stuck on the last part after doing the above, I suggest you ask it as a separate question, as that won't be related to reading it from Excel.
Good luck =)
Related
Can anyone help please?
When I sum two time value such as 09:00 and 22:30 I can get a result of 31:30 by formatting the cell using [h]:mm:ss.
However, whenever I try and do this with a subtotal row on an Excel table, it’s gives ridiculously large numbers?! For example, if I do the same as my first example, I get a result of something like 2million?!
Can anyone explain what I’m doing wrong? It works fine outside of the table but I need to use a table since I am populating the values from a PowerAutomate flow.
As above please see my example
Excel uses numbers to represent dates and times. It starts with 0.0 as midnight on Jan 1 1900 , 1.0 is midnight on Jan 2 1900 etc, each whole number is one day since Jan 1 1900 and times are represented using a fractional value. E.g. 0.5 is noon on Jan 1 1900, 2.25 is 6:00:00 am on Jan 3 1900 and so on.
When you sum date-times in Excel , it just sums these numerical values.
In your test case of adding two date-times 9:00am and 22:30 (=10:30pm) and getting 31:30, you are probably summing two fractional values only (e.g. 0.375 + 0.9375 ) to get a whole day and a bit ( = 1.3125) which the format you are using shows you 31:30.
Typically, date-times in Excel are both the whole number and the fraction. For recent dates these numbers can be quite large 44,926.5 is noon on Dec 31st 2022 for example. If you sum even a few of these, as numbers, and try to represent them as dates you will get an absurdly large number.
In order to help you better you will need to tell us the actually numerical value (not the formatted representation) of the underlying cells.
I am using a spreadsheet to record the intervals between certain medical events. Each event's timestamp is recorded in one column, so the interval between each event is the difference between consecutive cells (and the time since the last event uses now()).
First problem: I want to display the interval in days, hours and minutes. None of the built-in formats will do this, they report the days remaining after discarding complete months. So I am using this expression:
TEXT(TRUNC(C2-C1),"0") & " days " & TEXT(MOD(C2-C1,1),"hh "" hrs "" mm ""mins""")
which (e.g.) shows "46 days 13 hrs 44 mins". I was hoping there was a way to format a date/time value to show this rather than making the cell a string value, but I haven't been able to find one.
Second problem: I want to display the average value of all completed intervals in the same format. Because I can't average the string values produced by the previous expression I need to average the numeric equivalent (which I'd prefer not to have visible in the sheet) and then convert it to a string as for a single interval.
I can probably do this with a similar approach (if I don't run out of characters to enter the formula) but it seems to me that there must be a better way.
Ideally there is a solution which will work in Excel 2010. Has anyone solved a similar problem before and can give me some pointers?
Thanks, T
Edit: Some data to show what I am working with (I hope the image is readable). Here's a few lines from the sheet.
The formula for H2 etc. is
=IF(G2="c",NOW()-C2,"")
I5 is calculated as the difference between C5 and Cprev (where prev is chosen so that D5 and Dprev are both set). Obvious extension of this for J and K.
M2, M3 and M4 are respectively
=AVERAGEIF(K5:(INDIRECT("K"&(ROWS(K:K)))),"<>0")
=AVERAGEIF(J5:(INDIRECT("J"&(ROWS(J:J)))),"<>0")
=AVERAGEIF(I5:(INDIRECT("I"&(ROWS(I:I)))),"<>0")
Now, I can use a custom format for the values in H, I and J, and for M3 and M4, because these values will never exceed a few days. But values in K and M2 will be somewhere around 100 so I can't just format the raw value.
With custom formatting applied:
Here K6 and M2 say "27 days.." not "87 days..". That's what I'd like to fix nicely, hopefully without populating additional cells or writing a 3gl function to do it.
Date_Times in Excel are stored as days (with the decimal part representing parts of a day).
If the date matters, rather than just a number of days, then day zero is 1899/12/31.
Your first thought was right - do with formatting, not by turning a number into a string.
Entering date into A and time into B, with C=A+B is a good start, so that you can E.g. subtract one point in time from another without having to do anything about straddling midnight, month-ends etc, calculate averages etc.
Consolidating the comments already here: per https://support.microsoft.com/en-us/office/format-numbers-as-dates-or-times-418bd3fe-0577-47c8-8caa-b4d30c528309 you cannot get d for days above 31 (and it won't accept a format 0 hh:mm:ss )
I suggest that you do all your calculations using just numbers to get to say column M, and in N2 put =M2 etc, so you have the same values twice.
Then for formatting, use Format Cells | Number | Custom.
In column M put 0 "days".
In column N put hh "hours" mm "minutes".
I am trying to create an excel function that categorizes the time of day.
I have a column of DateTimes, Format: 3/3/2017 13:30 (but can change the format if needed). I need a second column declaring "ON" for the hours 9 pm to 5 am, "AM" for 5 am to 9 am, "BH" for 9 am to 5 pm, and "PM" for the hours 5 pm to 9 pm. I need weekends too but I figure I can pull those manually.
Result would look like (where I have column 1 and need to calculate column 2):
DateTime Time period
3/3/2017 13:30 BH
3/3/2017 17:30 PM
3/4/2017 3:30 ON
3/5/2017 5:30 AM
Make a table with the lower time and expected out put:
Then a simple VLOOKUP:
=VLOOKUP(MOD(A2,1),F:G,2)
We can save a few characters by only testing one end of each range. Once we have tested a value for less than 5 am, we no longer need to test to see if it is greater than 5 am. (The AND( statements aren't necessary.)
=IF(HOUR(A1)<5,"ON",IF(HOUR(A1)<9,"AM",IF(HOUR(A1)<17,"BH",IF(HOUR(A1)<21,"PM","ON"))))
If you want to detect weekends, wrap the whole thing in a weekend test. Two methods presented:
The better approach, suggested by #ScottCraner in the comments:
=IF(weekday(a1,2)>5,"WEEKEND","THE WHOLE THING")
The first argument for weekday( is obviously the date we are testing. The second forces Monday to be the first day of the week, which leaves Sat & Sun as the last two.
Combined with the rest, we would get:
=IF(weekday(a1,2)>5,"WEEKEND",IF(HOUR(A1)<5,"ON",IF(HOUR(A1)<9,"AM",IF(HOUR(A1)<17,"BH",IF(HOUR(A1)<21,"PM","ON")))))
An unnecessarily long, and somewhat fragile approach (breaks in non-English)
=IF(LEFT(TEXT(A1,"ddd"),1)="S","WEEKEND","THE WHOLE THING")
This works because TEXT(A1,"ddd") formats the date as the three-letter day of week. In English, at least, both weekend days starts with an "S", and we use left( to grab that first letter.
Together, it would end up looking like:
=IF(LEFT(TEXT(A1,"ddd"),1)="S","WEEKEND",IF(HOUR(A1)<5,"ON",IF(HOUR(A1)<9,"AM",IF(HOUR(A1)<17,"BH",IF(HOUR(A1)<21,"PM","ON")))))
Just to show a different way:
=IF(NETWORKDAYS(A2,A2),CHOOSE(SUM((({"5:00";"9:00";"17:00";"21:00"}*1)<MOD(A2,1))*1)+1,"ON","AM","BH","PM","ON"),"WEEKEND")
This is an array formula and must be confirmed with ctrl+shift+enter.
Can be extended as you like without getting in trouble of the bracket-limit.
Also like the Scott's answer: this works with times like 17:43. ;)
A little long, but works:
=IF(AND(HOUR(A2)>=9,HOUR(A2)<17),"BH",IF(AND(HOUR(A2)>=17,HOUR(A2)<21),"PM",IF(AND(HOUR(A2)>=5,HOUR(A2)<9),"AM","ON")))
I have date format in the following manner in the excel which is in string format:
Apr 1, 2016 12:37:06 PM
Apr 2, 2016 12:00:00 AM
Apr 1, 2016 9:50:22 AM
Apr 1, 2016 12:09:38 PM
Apr 1, 2016 6:53:03 PM
Apr 1, 2016 1:02:10 PM
I have tried converting it from general to date however excel still does not recognize it as date format. Need your advise as what can I try more to solve this.
Thanks in adavance !!
try =DATEVALUE("date string").
hope this helps
here is how it works
if still didn't work, then it has to do with windows date time setting.
Open Region and Language setting from Control Panel. Change the Long Date format to "MMMM dd,yyyy". Because this is the format your date string is formatted. You have to do this to get DATEVALUE() in excel to work. Now go back to your formula and see if it works.
After that, copy paste the formulas as value. Then you can change back to your preferred long date format again (or just leave it).
Couple of options for you:
Option 1
Text to Columns built in excel feature
Select all Dates for starters. They need to be in one column. On the Data ribbon, select Text to Columns. Light green back ground in the image above.
On the ensuing window that pops up select Fixed Width. Then select Next.
Adjust the columns so you get either a single column or the date in one column with the time in the other. Then select NEXT.
In the bottom preview window select the first column. Then up top select the Date radio button and from the pull down select MDY format. when ready click on FINISH button
Option 2
Formulas
Ripping out the text from the string and rebuilding the date using some ugly long formulas. So we are going to do this in parts so you can see how the big ugly gets made. When we are done we will copy the smaller formulas into one formula which will be big ugly and hard to read.
One of the annoying thing is you have the month as an abbreviation. Somewhere off to the side you will need to build a table and put all the abbreviations in one column and the corresponding month number in the column to the right. There may be other ways to do this but this is what I am going with for now.
(AA) | (AB)
Jan | 1
Feb | 2
Mar | 3
Apr | 4
May | 5
Jun | 6
Jul | 7
Aug | 8
Sep | 9
Oct | 10
Nov | 11
Dec | 12
So we can either work from biggest (Year) to smallest (seconds) or from left to right. lets tackle this starting from the left.
First thing first we need to pull the month out. Thankfully its on the LEFT side and we know its only 3 characters long. So we can go straight to the excel formula and hard code this in. And alternative approach would be to find the space. So first formula to find month is
=Left(A1,3)
Since we are going to need to know the number of that month we can convert it with a VLOOKUP function (INDEX/MATCH is another option). Lets put this in column F for now.
=VLOOKUP(Left(A1,3),$AA$1:$AB$12,2,0)
That should return the number 3 for us. you will have to adjust the AA1:AB12 to suit where you put the table.
Next we are going to pull the day. We know its 1 or two characters to the left of the first comma. We will use the FIND to determine where that is since it is not in a fixed position.
=FIND(",",A1)
So we know the date will start either 1 or 2 characters to the left. No harm in taking two as it will be a space or a number. So now lets use that knowledge with the MID formula and place the following in column G for now:
=--MID(A1,FIND(",",A1)-2,2)
the -- changed the text to a number (they are not actually needed in this case). So the next one is a little trickier but still doable. We need to find the Year. wouldn't you know it, its a fixed 4 characters long and starts just after that same first coma. So lets reuse our previous formula but tweak it a little and put the following in column H for now:
=--MID(A1,FIND(",",A1)+2,4)
Well now that we have our Month, Day and Year as numbers we can build our date using the DATE formula which we can drop in say column I:
=DATE(H1,F1,G1)
now if you thing you are ready to get started on the big an ugly we can substitute each of our previous equation into our date equation so its all done in one cell. That big formula is going to look as follows:
=DATE(MID($A1,FIND(",",$A1)+2,4),VLOOKUP(LEFT($A1,3),$AA$1:$AB$12,2,0),MID($A1,FIND(",",$A1)-2,2))
Now when I say all in one cell, I should add the caveat that you do need that helper information of the list of months...though there is a way around that too. So that takes care of the date process. now to do the time is very very similar.
We have two options The first option may not work for you since the datevalue formula did not work for you.
Option A - TimeValue
The nice thing about your time set up, is that the time is either 10 or 11 characters long from start to finish and if we take all 11 when its really only 10 we again are just snagging a space. So lets grab the RIGHT time and place this formula in the K column:
=TIMEVALUE(RIGHT($A1,11))
Now if that option does not work for you then we break it down the same way we did for the date.
Option B - Stripping Time
So lets look at patterns to see what we can figure out...that first ":" looks like a great identifier so lets find it the same way we did up for the date. Let build our time formula in column N:
=FIND(":",A1)
Let sub that straight into the MID formula to pull the hour
=MID($A1,FIND(":",$A1)-2,2)
And in Column O we will do the same for minutes and again with a bit of tweaking
=MID($A1,FIND(":",$A1)+1,2)
And since we know that the minutes keep a leading zero for single digit minutes we also know exactly where seconds are going to start. Lets put this formula in column P:
=MID($A1,FIND(":",$A1)+4,2)
So you might be wondering what to do about the AM/PM Lets grab that and put that in column Q
=RIGHT($A1,2)
So now that we have all that information what are we going to do to build the time. Well first things first is you need to know that Excel like 24 hour clocks. However it really saves it time as a decimal of a day. So 12 noon is actually stored as 0.5 or half a day. Another important thing to know is that the official supported time range for Excel is 00:00 to 23:59. There is no 24:00. now having said that 24 as an hour makes VBA crash unless you specifically deal with it in some special code. You can however get away with supplying 24 as an hour in excel formulas and get away with it sometimes. ok enough with the time lesson let build this final formula in column R:
=TIME(N1+IF(AND(Q1="PM",N1<>"12"),12,IF(AND(Q1="AM",N1="12"),-12,0)),O1,P1)
You will note there is an IF formula in there that deal with the AM PM as well as the special case of the 12 hour. The 12 is in quotes because N1 is a string and I had not converted it to a number.
now for the uglyness of back substituting our formula so it all in one cell.
=TIME(MID($A1,FIND(":",$A1)-2,2)+IF(AND(RIGHT($A1,2)="PM",MID($A1,FIND(":",$A1)-2,2)<>"12"),12,IF(AND(RIGHT($A1,2)="AM",MID($A1,FIND(":",$A1)-2,2)="12"),-12,0)),MID($A1,FIND(":",$A1)+1,2),MID($A1,FIND(":",$A1)+4,2))
And yeah that is so easy to read! I asked if you needed this in one column or two. Well you have the full formula for the date on its on and the full formula for time on its on. So if you need them together here is an interesting tid bit of information. Since Time is stored as decimal days, that means everything to the right of the decimal is time. It also means that everything to the left (or the integer portion) are days. So to have date time in one column, you just need to add the two formulas together...or as I refer to it as, the really big ugly equation...or at least one of the many that fall into that category:
=DATE(MID($A1,FIND(",",$A1)+2,4),VLOOKUP(LEFT($A1,3),$AA$1:$AB$12,2,0),MID($A1,FIND(",",$A1)-2,2))+TIMEVALUE(RIGHT($A1,11))
or if time value did not work for you
=DATE(MID($A1,FIND(",",$A1)+2,4),VLOOKUP(LEFT($A1,3),$AA$1:$AB$12,2,0),MID($A1,FIND(",",$A1)-2,2))+TIME(MID($A1,FIND(":",$A1)-2,2)+IF(AND(RIGHT($A1,2)="PM",MID($A1,FIND(":",$A1)-2,2)<>"12"),12,IF(AND(RIGHT($A1,2)="AM",MID($A1,FIND(":",$A1)-2,2)="12"),-12,0)),MID($A1,FIND(":",$A1)+1,2),MID($A1,FIND(":",$A1)+4,2))
Now this is just one solution on how to break it down with formulas. There are other options or route I could have gone at a couple of steps, but it should work for you regardless of what your system settings are. Here is a screen capture of the results on my system. note I hid empty columns that were not in use in order to make the image narrower. Column T has custom formatting of
mmm, d, yyyy h:mm:ss AM/PM
applied to it.
Option 3
VBA
I am sure someone will supply at some point. And look it happened before I could get to that stage! I don't know why 8)
As for the VBA solution, you can open VBA editor, add a new module and paste this code:
Function STRTODATE(ByVal dcell As Range)
Dim datecon As Date
datecon = dcell
STRTODATE = datecon
End Function
then you can use STRTODATE as a formula. Only really helpful, if it's one off. If it's something you'd do regularly on different files, then it can be annoying to paste this code to every workbook.
Have a list of dates in excel in the format (this comes originally from csv):
23/11/09 07:27:02
23/11/09 08:01:50
23/11/09 08:38:58
23/11/09 09:40:01
What I want to do is count the number of these falling between hour blocks, like 7-8, 8-9, 9-10 etc
Not sure how to get started, but one idea was just to put logic statements comparing the dates between these blocks, then adding the total "trues"
I can't get it to compare properly. When I type it the hour block marks,
e.g. 23/11/09 08:00
excel actually shows that as
23/11/2009 8:00:00 AM
and the compare doesn't work. Well actually it does the opposite of what it should.
that is:
=IF(C5>L1,IF(C5<M1,TRUE,FALSE),FALSE)
C5 being date in top codeblock, L1 and M1 being the hour blocks I manually entered in the second code block.
Has anyone got any ideas?
=hour(a1)=7
will return true if the time of the date/time value in cell A1 is between 7 and 8 (AM) and will otherwise return false.
Excel stores dates as number of days since 1900 or 1904 depending on your setting and the time as a fraction of the days. So 11:59 am 4th of July 1960 is held internally as '22101.4993055556'.
As such you cannot do plain charactrer string comparisons on dates. However ther ar lots of nifty time/date functions available to you.
You probably want :
=IF(HOUR(B1) > 8,IF(HOUR(B1)<12,"YES","NO"),"NO")
You should use Excel functions, like HOUR(), to extract the parts of the times, and apply the logic tests to those extracted values.