I am using Now.Hour to return an integer for a query. Here is my sql query:
SELECT * FROM DATABASE.dbo.STORE_LIVE WHERE DELIVERY_HOUR=Now.Hour
However, at 12 midnight, my query is not returning any row since Now.Hour only returns '0' but the DELIVERY_HOUR in the database has a range of 1 to 24.
In MSDN Time Format, these are the only available formats:
"H"
The hour, using a 24-hour clock from 0 to 23.
6/15/2009 1:45:30 AM -> 1
6/15/2009 1:45:30 PM -> 13
"HH"
The hour, using a 24-hour clock from 00 to 23.
6/15/2009 1:45:30 AM -> 01
6/15/2009 1:45:30 PM -> 13
How should I customized Now.Hour to return from 1 to 24 without resorting to a conditional statement for interval 0 or 23?
Thanks
I would suggest you create an extension method which returns 1 - 24 instead of 0 - 23.
Put this code into a module:
Imports System.Runtime.CompilerServices
<Extension()>
Private Function GetCustomHour(aDate As Date) As Integer
Dim hour = aDate.Hour
Select Case hour
Case 0 : Return 24
Case Else : Return hour
End Select
End Function
Then in your code:
Instead of Now.Hour use Now.GetCustomHour
However, I would strongly advise that you change your database to store valid times as this is only going to cause more problems along the way (there is no such hour of the day as 24)
Related
I've a PSQL table like this:
Order
Start_Hour
Start_Minute
Finish_Hour
Finish_Minute
10
10
15
12
15
10
12
15
14
15
10
16
00
17
00
And I need to calculate by a query the total time expressed in hours that I spent to finish the order. In this scenario I expect to have a total of 5 hours:
12:15 - 10:15 = 2 hours
14:15 - 12:15 = 2 hours
17:00 - 16:00 = 1 hours
The query result must be 5.
The idea was concatenate start hour/minute and finish hour/minute, convert them to hour, make the difference, calculating the total.
SELECT (Start_Hour & ":" & Start_Minute) as start, (Finish_Hour & ":" & Finish_Minute) as finish
FROM OrderDetails
But when I try to convert them to HH:MM using cast or convert but I got errors.
Any advice?
Thank you
This query uses make_time as Adrian Klaver suggests.
select
"Order",
sum(extract(hour from
make_time("Finish_Hour", "Finish_Minute", 0) -
make_time("Start_Hour", "Start_Minute", 0))
) as duration
from the_table
group by "Order";
However I have remarks about your data design. Hour and minute are not enough for storing time because (apart from missing precision and other reasons) the end time might be over midnight. You have a specific data type for this - timestamp. I would suggest something like
create table the_table
(
order_nr integer,
start_time timestamp,
finish_time timestamp
);
Also note that using mixed case names in Postgresql requires double-quoting.
Use make_time:
select make_time(12, 15, 0) - make_time(10, 15, 0);
?column?
----------
02:00:00
Where in your case you would substitute in Start_Hour, Start_Minute, Finish_Hour, Finish_Minute.
I have a series of data that I get from an access control device, the data is the following:
Cardno, Pin, Verified, DoorID, EventType, InOutState, Time_second
3189959,13978762,4,2,0,0,676132501
Time_second(676132501) should be "2021-01-14 14:58:54.000"
this is my code
Dim sDate As Integer = 676132501
Dim dtDateTime As System.DateTime = New DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)
dtDateTime = dtDateTime.AddSeconds(sDate).ToLocalTime()
the value returned is : #6/5/1991 10:35:01 AM#, please help
A quick google search of those field names you gave in the question landed on a technical spec doc of something called "PullSDK", which appears to be what you're using. I won't link to it here because I could not find an official source.
The doc gives a formula for decoding these timestamps. Translated to VB.Net it is as follows:
Function DecodeDateTime(ByVal t As Integer) As DateTime
Dim year, month, day, hour, minute, second As Integer
second = t Mod 60
t /= 60
minute = t Mod 60
t /= 60
hour = t Mod 24
t /= 24
day = t Mod 31 + 1
t /= 31
month = t Mod 12 + 1
t /= 12
year = t + 2000
Return New DateTime(year, month, day, hour, minute, second)
End Function
The value you gave, 676132501 is decoded as 2021-01-15 15:35:01 - which is slightly different than your stated expectation. You might want to carefully check the source of that data to verify your assumptions.
As an aside - in evaluating that formula, no amount of adding seconds to some base value would suffice. This is because they've encoded the day into a space that always has 31 values within a month - even for months with less than 31 days. That makes this encoding inefficient, as there will be some values that represent dates that don't actually exist.
I am trying to subtract 2 dates from each other but it seems that it is not subtracting properly and i am not sure what i am doing wrong here. I am using case statement to flag as 1 if the difference between the dates are less than 90 days else flag it as 0. But it is always flagging as 1 even if the difference between the dates are greater than 90 days. I am PostgreSQL here and here is my case statement:
CASE WHEN EXTRACT(DAY FROM CAST(SVS_DT AS DATE) - CAST(DSCH_TS AS DATE)) <90
THEN 1 ELSE 0 END AS FU90
example of the dates are here:
SVS_DT DSCH_TS
2013-03-22 00:00:00 2010-05-06 00:00:00
it is suppose to flag as 0 in this case but it is flagging as 1 because the difference between these 2 dates are greater than 90 days.
extract of a day returns the day element of a date. Since days are always between 1 and 31, the maximum difference is 30, and cannot be larger than 90.
Subtracting dates returns the difference in days, as an integer. So you need only drop the extract calls:
CASE WHEN (CAST(SVS_DT AS DATE) - CAST(DSCH_TS AS DATE)) < 90 THEN 1
ELSE 0
END AS FU90
you can use below one:
CASE WHEN (EXTRACT(EPOCH FROM (DATE_COLUMN_2 - DATE_COLUMN_1)) < (90*24*60*60)
THEN 1 ELSE 0 END AS FU90
here it returns the deference in seconds so you need to convert 90 days into seconds
A slightly shorter CAST version.
SELECT CASE WHEN SVS_DT::DATE - DSCH_TS::DATE < 90
THEN 1
ELSE 0
END
AS FU90
We can also do it without using any EXTRACT or CAST keyword like:
SELECT CASE WHEN (DATE(SVS_DT)- DATE(DSCH_TS)) < 90
THEN 1
ELSE 0
END AS FU90
I have the following formula to convert the duration into hours. I want to do case where any duration which is 15 min or more Is considered as an hour. for instance 1 hour 15 min will be calculated as 2 hrs, 2 hrs 15 min will be calculated as 3 hrs and so on. if it is less than 15 min after an hour than it will be the hour. eg 1 hr 5 min will be considered 1 hour.
((Case T0.DurType when 'M' then (T0.Duration/100)/.60 when 'D' then (T0.Duration*8) Else T0.Duration End)) as 'Duration'
Are you doing this in SQL or as a formula field in Crystal?
Is case syntax required for some reason, or is that simply the approach you initially chose?
What unit of time does each increment of Duration represent, 1 second, 1 minute?
Assuming the following:
this is in sql
case syntax is not required
each increment of Duration is 1 minute
Then here is your correct formula, using ceiling rather than case:
ceiling(T0.Duration/60) as "Duration"
That will increment any partial decimal value to the next highest integer, e.g., 75 minutes / 60 = 1.25 hours, and ceiling will increment to 2. 180 minutes / 60 = 3.00 hours and ceiling will output 3.
EDIT:
I'm not sure what you mean by achieving it in sql & crystal... if you calculate it in sql, it's passed to Crystal and won't need any further transformation. Either way, here's both solutions:
Crystal: Assumes minutes are used. the "\" operator is integer division, so the decimal is dropped. A simple if/then/else iif is used to add either 1 or zero if the remainder minutes are 15 or more:
MINUTES \ 60 + IIF (MINUTES mod 60 >= 15,1 , 0)
In SQL (MySQL syntax, MSSQL/TSQL may vary) achieves the same as follows:
floor(MINUTES / 60) + IF( (MINUTES % 60) >= 15,1 , 0)
I am building a report in SSRS.
In design mode it looks like this:
tat2 are values 1 through 192 and appear on the report like this:
1
2
3
...
192
I would like to know if there's a way to instead do something like this:
DAY 1 12:00AM
DAY 1 1:00AM
DAY 1 2:00AM
...
DAY 7 9:00PM
...
DAY 8 12:00AM
In other words, I would like to turn the numbers 1 through 192 into hours and days.
You could use Date.AddHours() for this - just create a new Date that's the start of any year and use
Date.AddHours(Fields!YourNumericField.Value)
This way you get rolling hours - will you ever have more than 192? What's the maximum range, as this would roll-over at 365. You could just mix and match and do an expression though like:
=Math.Ceiling(Fields!YourNumericField.Value / 24) & SomeDate.AddHours(Fields!YourNumericField.Value)
Something like that
I don't have SSRS on this machine to test though :P
Edit:
Ok so to get the base date you can use new DateTime(year, month, day)
http://msdn.microsoft.com/en-us/library/system.datetime.aspx
So the expression
="DAY " & Math.Ceiling(Fields!tat2.Value / 24) & " " & format(new DateTime(2000, 1, 1).AddHours(Fields!tat2.Value), "hh:mm tt")
This should give:
DAY 1 10:45 AM
Should work - if you want to change the format of the 10:00AM bit check this reference:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
"HH:mm" gives you 24 hour time + minutes e.g. 23:54
"hh:mm tt" is 12 hour e.g. 12:00 PM
Have a play
This can be easily done in the underlying query - not sure about doing it in SSRS:
SELECT
Tat2 / 24 + 1 as Day,
CAST(Tat2 % 24 AS CHAR(2)) + ':00 ' +
CASE WHEN Tat2 % 24 > 12 then 'PM' else 'AM' end as AMPM
FROM YourTable
This won't, of course, handle more than 365 days, because it doesn't months or years.