Updating a Duration Field by Plugin - dynamics-crm-2011

Has anyone had to update a Duraton field from within a plugin?
On the UI it is fairly intelligent, you can type
5 minutes
7 //defaults to minutes
3 hours
And it will workout what you need.
Assuming the field is called new_foo, what value should I assign? Int?
var e = new Entity("new_bar");
e.Attributes("new_foo", 5);//5 minutes?
Double?
var e = new Entity("new_bar");
e.Attributes("new_foo", 5.00);//5 minutes?
Other ideas?

Duration is a format for the Whole Number type, so by code you need to set an Int32 value (in this case not negative or it will throw an exception)
The value is always considered in minutes, so if you want to put 3 hours you need to set the field value to 180 (60 minutes x 3 hours), 1 day is 1440 (60 minutes x 24 hours) and so on.
By interface you can set using decimals, but it's always a representation of an integer value (for example 1.5 hours equals 90 minutes)

Related

Summing time fields over 24 hours in Power Query

I have a Power Query in excel linked to another file. This file has a time column. I understand that M language will not sum above 24 hours automatically without some work as it uses a datetime reference hence if I import a time of 25 hours it reverts back 2 hours to 1 hour...
In the 3rd column along in my image below using the second row as a reference, this is actually supposed to read 47:47:38. How can I get the instances where the value is above 24 hours to show the true hours?
I have tried using duration.hours(#hours()) this also does not work for some reason.
The same data from the source excel file is below also
Power Query doesn't have custom formats for how it displays data. If you have it read your data as a Duration instead of a DateTime it will display as [d].hh.mm.ss format, but still not with the total hours. Ultimately though this doesn't really matter because even when your data is formatted to display total hours in Excel, it's really being stored internally as days+hours+minutes+seconds. So how it displays in Power Query doesn't matter, as you can just use the hour formatting wherever you output the data to.
Now if you need to use the hours for a calculation between something that isn't another Duration, you can extract the hours by doing
Duration.Days([Your Hours]) * 24 + Duration.Hours([Your Hours])
Or now that I look at it, there is also a TotalHours function that gives you the hours plus mm:ss as a fractional amount of that
Duration.TotalHours([Your Hours])
Power BI doesn't handle this case very gracefully. A solution could be to convert the duration to a number to make it additive (so you can perform calculations and aggregations) and when you need to visualize it, to convert it to the desired format (HH:MM:SS).
Duration and Time are often confused. When such Excel files are read, the type of the column usually is DateTime, and date 1899-12-31 is added to the "time" part. You can change the data type of the column to be Decimal Number, but the "zero point" in Excel unfortunately is one day off (1899-12-30), so you need to subtract 1 from the result to get the actual "number of days" of the duration (i.e. 0.25 means 06:00:00).
So you must perform some conversion of the data. I would make a new column in the model to get the duration in the lowest granularity that I need (seconds in your example). In Power Query Editor add a custom column to calculate the duration in seconds (where Column1 is the name of the original duration column):
Duration in seconds = Duration.TotalSeconds([Column1] - #datetime(1899, 12, 31, 0, 0, 0))
Make sure the data type of this column is Whole Number (change it if necessary). Here 9144 seconds are calculated as 2 * 3600 + 32 * 60 + 24, or 02:32:24. Now you can calculate a sum on this column to get total duration in seconds for example. But when you visualize this column, don't do it directly, but make a measure to convert the data to the desired format. It could me made like this:
Measure Duration =
VAR duration_in_seconds = SUM(Sheet1[Duration in seconds])
VAR hours = ROUNDDOWN ( duration_in_seconds / 3600; 0 )
VAR minutes = ROUNDDOWN ( MOD ( duration_in_seconds; 3600 ) / 60; 0 )
VAR seconds = INT ( MOD ( duration_in_seconds; 60 ) )
RETURN hours & ":" & FORMAT(minutes; "00") & ":" & FORMAT(seconds; "00")
duration_in_seconds variable hold the total duration in seconds of the data in the context. From it we are calculating hours, minutes and seconds and constructing a string to represent the duration in the desired format. FORMAT is used to make sure there is a leading zero in case minutes or seconds are less than 10.
Here is how all three columns looks like when visualized:
Hope this helps!

How to check if a time noted is within designated window or range in Excel

I need to check if a time of collection is within allowed time window or not.
For e.g.
A B C
1 10.36 10.30 1 min out of +/- 5 minutes window
2 10.24 10.30 1 min out of +/- 5 minutes window
A1 here time of collection of data, and B1 is the scheduled time. The acceptable window or range for this is +/- 5 minutes out of window. In this case the time of collection is 1 min out of +/- 5 minutes window. Similar example is shown in row 2. How can i get C1 to show the message as above which can account for + 5 minutes and - 5 minutes scenarios?.
Thanks in advance.
=IF(ABS(A1-B1)>(5/1440),"Problem!","OK")
5/1440 is 5 minutes (1440 minutes in a full day)
Use this formula¹ in C1 and fill down as necessary,
=ROUND(MAX((ABS(A1-B1)-0.05)*100, 0), 0)
Use the following custom number format on column C,
0 \mi\n out of ± 5 \mi\nut\e wi\n\dow
The advantages of a custom number format is that the numbers remain numbers and are available for future calculations (e.g. SUM, AVERAGE, etc) while displaying the text you wish to show. Note the right-alignment in the cells indicating true numbers.
¹ This formula depends on the time values being mixed numbers and not true time. If the time values are true time with a non-EN-US number format then additional maths may have to be applied to the formula.

Convert 'x hrs y min z sec' to seconds

a) So I have a huge folder of .csv data with a column about time duration where the cells are 'x min y sec' (e.g. 15 min 29 sec) or 'x hrs y min z sec' (e.g. 1 hrs 48 min 28 sec). The cells are formatted by text.
I want to batch change them to the number of seconds, but I have no idea where to start. I can't get the data in another format.
I thought about somehow using 'hrs', 'min' or 'sec' as delimiters, but I don't know how to move from there. I also thought about using ' ' as delimiters, but then the first column is filled with either hours or minutes depending on the time duration.
I also thought about using PostgreSQL's SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'), but I haven't been able to work out how to use this on a column from a table.
b) Is there a better way to change this time format 'Fri Mar 14 11:29:27 EST 2014' to epoch time? Right now I'm thinking of using macros in Excel to get rid of 'Fri' and 'EST', then put the columns back together, then use the to_timestamp function in PostgreSQL.
In Excel if you have data in only those 2 formats and starting from A2 you can use this formula in B2 copied down to get the number of seconds:
=IFERROR(LEFT(A2,FIND("hrs",A2)-1)*3600,0)+SUM(MID(0&A2,FIND({"min","sec"},0&A2)-3,2)*{60,1})
It finds the relevant text then gets the number in front for each and multiplies by the relevant number to get seconds
You can do:
SELECT EXTRACT(EPOCH FROM column_name::interval)
FROM my_table;
The interval can use the regular time units (like hour), abbreviations thereof (hr) and plurals (hours). I am not sure about a combination of plural and abbreviation (hrs) though. If that does not work, UPDATE the column and replace() the sub-string "hrs" to "hours".
If you want to save the number of seconds in your table, then you convert the above statement into an UPDATE statement:
UPDATE my_table SET seconds_column = extract(epoch FROM column_name::interval);
I would split with space as the delimiter, then examine the second column. If it contains the string "hrs", then your seconds answer is:
3600 * column 1 + 60 * column 3 + column 5
Otherwise it is:
60 * column 1 + column 3

Rounding Up Minutes above 8, 23, 38, 53 to the nearest quarter hour

Here’s a challenge for someone. I’m trying to round session times up to the nearest quarter hour (I report my total client hours for license credentialing)
8 minutes or above: round up to 15
23 minutes or above: round up to 30
38 minutes or above: round up to 45
53 minutes or above: round up to 60
Ex: in the first quarter hour, minutes below 8 will be their exact value: 1=1, 2=2, 3=3.
When 8 is entered, it is automatically rounded up to 15 (the same holds true for the rest of the hour: ex: 16=16, 17=17, 18=18, 19=19, 20=20, 21=21, 22=22. But 23 through 29 are all rounded up to 30.
Ideally, I could enter both hours and minutes in a single column, ex: 1.54
However, I realize that it may be necessary to create a separate column for hours and minutes in order to make this work (i.e., so that my formula is only concerned with rounding up minutes. I can add my hours and minutes together after the minutes are rounded.) Thus:
Column A = Hours (3 hours maximum)
Column B = Minutes
Column C = Minutes Rounded up to nearest ¼ hour
Column D = Col A + Col C
In column B I would like to enter minutes as 1 through 60 (no decimal- i.e., in General, not Time format)
38 minutes in column B would automatically be rounded up to 45 minutes in column C
Does anyone have any ideas? How can I do this using the fewest number of columns?
[A Previously posted question - "Round up to nearest quarter" - introduces the concept of Math.Ceiling. Is this something I should use? I couldn't wrap my head around the answer).
With Grateful Thanks,
~ Jay
How's this go?
DECLARE #time DATETIME = '2014-03-19T09:59:00'
SELECT CASE
WHEN DATEPART(mi, #time) BETWEEN 8 AND 15 THEN DATEADD(mi, 15-DATEPART(mi, #time), #time)
WHEN DATEPART(mi, #time) BETWEEN 23 AND 30 THEN DATEADD(mi, 30-DATEPART(mi, #time), #time)
WHEN DATEPART(mi, #time) BETWEEN 38 AND 45 THEN DATEADD(mi, 45-DATEPART(mi, #time), #time)
WHEN DATEPART(mi, #time) BETWEEN 53 AND 59 THEN DATEADD(mi, 60-DATEPART(mi, #time), #time)
ELSE #time
END
Assume "sessions" is your table (CTE below contains 2 sample records), with session start time & end time stored (as noted in comments above, just store these data points, don't store the calculated values). You might be able to do the rounding as below. (not sure if this is what you want, since it either rounds up or down... do you not want to round down?)
;WITH sessions AS (
SELECT CAST('20140317 12:00' AS DATETIME) AS session_start, CAST('20140317 12:38' AS DATETIME) AS session_end
UNION ALL
SELECT CAST('20140317 12:00' AS DATETIME), CAST('20140317 12:37:59' AS DATETIME) AS session_end
)
SELECT *, DATEDIFF(MINUTE, session_start, session_end) AS session_time
, ROUND(DATEDIFF(MINUTE, session_start, session_end)/15.0, 0) * 15.0 AS bill_time
FROM sessions;
EDIT:
Hi Jay, I don't think you mentioned it is an Excel problem! I was assuming SQL. As Stuart suggested in a comment above, it would be helpful if you modified your question to indicate it is for Excel, so that others can possibly get help from this dialog in the future.
With Excel, you can do it with two columns that contain the session start date and time (column A) and session end date and time (column B), plus two formulas:
Column C (Actual Minutes) = ROUND((B1-A1) * 1440,0)
Column D (Billing Minutes) = (FLOOR(C1/15, 1) * 15) + IF(MOD(C1,15) >= 8, 15, MOD(C1,15))
This is what my table looks like:
3/18/2014 12:00 3/18/2014 12:38 38 45
3/18/2014 14:00 3/18/2014 14:37 37 37

Excel Function For If Then Statement for Range of Times

=IF(I44<"0:01","0",IF(I44<"0:30","2:00",IF(I44<"1:00","2:30",IF(I44<"1:30","3:00",IF(I44<"2:00","3:30",IF(I44<"2:30","4:00",IF(I44<"3:00","4:30",IF(I44<"3:30","5:00",IF(I44<"4:00","5:30",IF(I44<"4:30","6:00",IF(I44<"5:00","6:30",IF(I44<"5:30","7:00",IF(I44<"6:00","7:30",IF(I44<"6:30","8:00",IF(I44<"7:00","8:30",IF(I44<"7:30","9:00",IF(I44<"8:00","9:30",IF(I44<"8:30","10:00",IF(I44<"9:00","10:30",IF(I44<"9:30","11:00",IF(I44<"10:00","11:30","")))))))))))))))))))))
(Left out the code tags so you dont have to scroll 30 pages to the right)
I am using this function to add specific amounts of time to specific range of time and this seems like there must be a better method of doing this.
For example: for a input time of < 30 min, would output 2:00 hr, for input time of < 1:00 would output 2:30 ... and for each 30 min increment in the input the output would increment by 30 minutes
Perhaps just round down to the next half hour then add 2 hours, i.e
=IF(I44=0,0,FLOOR(I44,"0:30")+"2:00")
[with an IF to deal with zero values]
Format result cell as a time value, e.g. h:mm or similar

Resources