Case,Substring and concat within a cognos Data Item Expression - informix

I'm scratching my head trying to work with time functions within Cognos 10.2.1 (Report Studio), using an Informix db as a data source.
My time field is stored as a smallint, 4 digits, representing the 24 hour clock. I am trying to get the time to display as 6:00pm, 11:30am, 3:00pm, etc. I have a separate data expression that calculates the string 'AM' or 'PM' depending on the hour value, but I'm running into some errors when doing the overall concat/substring function.
case when char_length([Query1].[beg_tm]) = 4
then (substring(cast([StartTime], char(5)), 1, 2)) || ':' || (substring (cast ([StartTime], char(5)), 3, 2)) || ([beg_AMPMcalc])
when char_length([Query1].[beg_tm]) = 3
then (substring(cast([StartTime], char(5)), 1, 1)) || ':' || (substring(cast ([StartTime], char(5)), 3, 2)) || ([beg_AMPMcalc])
else '--'
end

Why not use DATETIME HOUR TO MINUTE; at least you then only have to deal with converting 24 hour clock to 12 hour clock. Is midnight stored as 0 and noon as 1200, and the minute before midnight as 2359? Cognos uses a fairly modern version of Informix, I believe, so you should be able to use the TO_CHAR function:
DROP TABLE IF EXISTS times;
CREATE TEMP TABLE times(p_time SMALLINT);
INSERT INTO times VALUES(0);
INSERT INTO times VALUES(59);
INSERT INTO times VALUES(100);
INSERT INTO times VALUES(845);
INSERT INTO times VALUES(1159);
INSERT INTO times VALUES(1200);
INSERT INTO times VALUES(1259);
INSERT INTO times VALUES(1300);
INSERT INTO times VALUES(1815);
INSERT INTO times VALUES(2359);
SELECT TO_CHAR(CURRENT HOUR TO MINUTE, "%I:%M %p"),
p_time,
DATETIME(00:00) HOUR TO MINUTE + MOD(p_time, 100) UNITS MINUTE + (p_time/100) UNITS HOUR,
TO_CHAR(DATETIME(00:00) HOUR TO MINUTE + MOD(p_time, 100) UNITS MINUTE + (p_time/100) UNITS HOUR, "%I:%M %p")
FROM times;
Output:
03:49 AM 0 00:00 12:00 AM
03:49 AM 59 00:59 12:59 AM
03:49 AM 100 01:00 01:00 AM
03:49 AM 845 08:45 08:45 AM
03:49 AM 1159 11:59 11:59 AM
03:49 AM 1200 12:00 12:00 PM
03:49 AM 1259 12:59 12:59 PM
03:49 AM 1300 13:00 01:00 PM
03:49 AM 1815 18:15 06:15 PM
03:49 AM 2359 23:59 11:59 PM
I'm using a database server that has its local time set to UTC, and I'm in time zone -07:00 (US/Pacific); the current time isn't the middle of the night where I am.

Related

Determining Late Shipments with a Function

I am trying to write an if statement with 2 conditions.... one of them being if it has been longer than 60 minutes and the other condition is that it is "late". Example, I am trying to determine when shipments are late over an hour but I don't want it to count when shipments are early, just when they are late. Here is the equation I had originally buts its counting when shipments are greater than 60 minutes early as well:
IF HDIFF ( SHIPMENT_INDIVIDUAL_MOVE_COSTING.LOAD_DATE_FIELDS.SL_LD_DROP_ACTUAL_DATE , SHIPMENT_INDIVIDUAL_MOVE_COSTING.LOAD_DATE_FIELDS.SL_LD_DROP_APPT_START_DATE , 'Minute' , 'D6' ) GT 60 THEN 1 ELSE 0
Any assistance or thoughts are appreciated.... I feel stuck
I've tried some code with your problem, and I think it's working as intended.
The code I've used:
-* IGNORE THESE LINES, ONLY FOR DATA SAMPLING
FILEDEF ORDERS DISK orders.ftm (APPEND
-RUN
-*
EX -LINES 6 EDAPUT MASTER,ORDERS,CV,FILE
FILENAME =ORDERS, SUFFIX=FIX
SEGNAME=ORDERS, SEGTYPE=S0, $
FIELD=ORDER_COD_PROD, ALIAS=ORDER_COD_PROD, USAGE=A21 ,ACTUAL=A1 ,$
FIELD=ORDER_DELIVERY, ALIAS=ORDER_DELIVERY, USAGE=HYYMDS,ACTUAL=A30 ,$
FIELD=ORDER_TRACKING, ALIAS=ORDER_TRACKING, USAGE=HYYMDS,ACTUAL=A30 ,$
-*
-WRITE ORDERS 12020/11/20 11:20 2020/11/20 12:45
-WRITE ORDERS 22020/11/20 11:40 2020/11/20 12:45
-WRITE ORDERS 32020/11/20 11:50 2020/11/20 12:45
-WRITE ORDERS 42020/11/20 11:55 2020/11/20 12:45
-WRITE ORDERS 52020/11/20 12:00 2020/11/20 12:45
-*
DEFINE FILE ORDERS
HOW_LATE/D12.2 = HDIFF(ORDER_TRACKING, ORDER_DELIVERY, 'MINUTE', 'D12.2');
DEC_LATE/A10 = IF HOW_LATE GE 60 THEN 'Late' ELSE 'Early';
END
-RUN
-*
TABLE FILE ORDERS
PRINT
ORDER_COD_PROD AS 'ID'
ORDER_DELIVERY AS 'Day/Time Compromised'
ORDER_TRACKING AS 'Day/Time Now'
HOW_LATE AS 'Late (Minutes)'
DEC_LATE AS 'Late (Literal)'
END
-RUN
The result is:
PÁG 1
ID Day/Time Compromised Day/Time Now Late (Minutes) Late (Literal)
1 2020/11/20 11:20:00 2020/11/20 12:45:00 85,00 Late
2 2020/11/20 11:40:00 2020/11/20 12:45:00 65,00 Late
3 2020/11/20 11:50:00 2020/11/20 12:45:00 55,00 Early
4 2020/11/20 11:55:00 2020/11/20 12:45:00 50,00 Early
5 2020/11/20 12:00:00 2020/11/20 12:45:00 45,00 Early
This is fictitious data, but you can see I've created a file with several fields, one with product code, other with the time the product has to be delivered in Timestamp format, and lastly, other with a field that represents the "moment" of the report. With these 2 Timestamp we can use the function HDIFF to find the difference in minutes from both moments, as Double. With this conversion, we can check if it's less than 60 min (LT) or greater or equal than 60 (GE).
Regards.

How to set two different scheduler for single Jenkins job

I just want to run the job twice per week. Every Sunday 11 PM and every Friday 11 pm I just want to trigger the job automatically. I successfully implemented for one scheduler but not sure how to use two in single .
Sunday scheduler :
H 11 * * 0
Friday scheduler:
H 11 * * 6
For scheduling the job below pattern need to be followed:-
0 - Sun Sunday
1 - Mon Monday
2 - Tue Tuesday
3 - Wed Wednesday
4 - Thu Thursday
5 - Fri Friday
6 - Sat Saturday
7 - Sun Sunday
For your case you can follow the below:-
0 23 * * 0,5
You better understanding of "H" in Jobs Scheduler follow this:
Maybe something like this. Note there's a couple changes from your example, changed 11 to 23, 11 is 11am, 23 is 11pm and using 5 instead of 6 for Friday.
H 23 * * 0,5
But note with the "H" it isn't going to run at exactly 11pm, from the Jenkins docs:
The H symbol can be thought of as a random value over a range, but it
actually is a hash of the job name, not a random function, so that the
value remains stable for any given project.
If you want it to run closer to 11pm, maybe something like this
H(1-5) 23 * * 0,5

Datetime Diff in ROR

I have a ruby application where i need to get date-time difference in Days-Hours-Minutes format. For this i m using following function
def duration (from_time, to_time)
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
distance_in_seconds = ((to_time - from_time).abs).round
secs = distance_in_seconds.to_int
mins = secs / 60
hours = mins / 60
days = hours / 24
if days > 0
"#{days}d #{hours % 24}h"
elsif hours > 0
"#{hours}h #{mins % 60}m"
elsif mins > 0
"#{mins}m"
end
end
The above called like this from another function
duration(aw_updated, Time.now)
But some time it gives me wrong result,
when i display above values
aw_updated is 2012-09-19 04:23:34 UTC
Time.now is 2012-09-19 16:33:09 +0530
Time.now.utc is 2012-09-19 11:03:09 UTC
And
Diff is 6h 26m
But my system time is 2012-09-19 16:33:09
Not sure where i m doing wrong , some UTC issue?
please advise
For correct answer your both time should have same timezone utc in this case
So it is converting 2012-09-19 16:33:09 +0530 into utc which gives 2012-09-19 11:03:09 UTC and hence difference is Diff is 6h 26m
Would enter this as a comment but can't yet.
I haven't looked in detail at your function but do you have to build it from scratch? Why don't you use the Ruby in built DateTime class. You can parse strings to DateTime objects, do the calculation and use the strftime method to output the time in a format that you want

Rails times oddness : "x days from now"

when users sign up to one of my sites for a free trial, i set their account expiry to be "14.days.from_now". Then on the home page i show how many days they have remaining, which i get with:
(user.trial_expires - Time.now)/86400
(because there are 86400 seconds in a day, ie 60 * 60 * 24)
The funny thing is, this comes out as more than 14, so gets rounded up to 15. On closer investigation in the console this happens for just two days in the future (if you know what i mean). eg
>> Time.now
=> Fri Oct 29 11:09:26 0100 2010
>> future_1_day = 1.day.from_now
=> Sat, 30 Oct 2010 11:09:27 BST 01:00
#ten past eleven tomorrow
>> (future_1_day - Time.now)/86400
=> 0.999782301526931
#less than 1, what you'd expect right?
>> future_2_day = 2.day.from_now
=> Sun, 31 Oct 2010 11:09:52 GMT 00:00
>> (future_2_day - Time.now)/86400
=> 2.04162248861183
#greater than 2 - why?
I thought maybe it was to do with timezones - i noticed that the time from 1.day from now was in BST and the time 2 days from now was in GMT. So, i tried using localtime and got the same results!
>> future_2_day = 2.day.from_now.localtime
=> Sun Oct 31 11:11:24 0000 2010
>> (future_2_day - Time.now)/86400
=> 2.04160829127315
>> (future_2_day - Time.now.localtime)/86400
=> 2.04058651585648
I then wondered how big the difference is, and it turns out that it is exactly an hour out. So it looks like some time zone weirdness, or at least something to do with time zones that i don't understand. Currently my time zone is BST (british summer time) which is one hour later than UTC at the moment (till this sunday at which point it reverts to the same as UTC).
The extra hour seems to be introduced when i add two days to Time.now: check this out. I start with Time.now, add two days to it, subtract Time.now, then subtract two days of seconds from the result, and am left with an hour.
It just occurred to me, in a head slapping moment, that this is occurring BECAUSE the clocks go back on sunday morning: ie at 11.20 on sunday morning it will be two days AND an extra hour from now. I was about to delete all of this post, but then i noticed this: i thought 'ah, i can fix this by using (24*daynum).hours instead of daynum.days, but i still get the same result: even when i use seconds!
>> (Time.now + (2*24).hours - Time.now) - 86400*2
=> 3599.99969500001
>> (Time.now + (2*24*3600).seconds - Time.now) - 86400*2
=> 3599.999855
So now i'm confused again. How can now plus two days worth of seconds, minus now, minus two days worth of seconds be an hour worth of seconds? Where does the extra hour sneak in?
As willcodejavaforfood has commented, this is due to daylight saving time which ends this weekend.
When adding a duration ActiveSupport has some code in it to compensate for if the starting time is in DST and the resulting time isn't (or vice versa).
def since(seconds)
f = seconds.since(self)
if ActiveSupport::Duration === seconds
f
else
initial_dst = self.dst? ? 1 : 0
final_dst = f.dst? ? 1 : 0
(seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
end
rescue
self.to_datetime.since(seconds)
end
If you have 11:09:27 and add a number of days you will still get 11:09:27 on the resulting day even if the DST has changed. This results in an extra hour when you come to do calculations in seconds.
A couple of ideas:
Use the distance_of_time_in_words helper method to give the user an indication of how long is left in their trial.
Calculate the expiry as Time.now + (14 * 86400) instead of using 14.days.from_now - but some users might claim that they have lost an hour of their trial.
Set trials to expire at 23:59:59 on the expiry day regardless of the actual signup time.
You could use the Date class to calculate the number of days between today and the expire date.
expire_date = Date.new(user.trial_expires.year, user.trial_expires.month, user.trial_expires.day)
days_until_expiration = (expire_date - Date.today).to_i
Use since, example:
14.days.since.to_date

Ruby on Rails - Working with times

If in a database (MySQL), I have a datetime column (ex. 1899-12-30 19:00:00), how do I sum 1 day to it?
Following http://corelib.rubyonrails.org/classes/Time.html#M000240
If I want to add 1 day, it actually adds 60*60*24 days (86,400 days)
r=Record.find(:first)
=>Sat, 30 Dec 1899 19:00:00 -0600
r.date + (60*60*24)
=>Fri, 20 Jul 2136 19:00:00 -0600
But if I do this it actually adds 1 day:
t = Time.now
=>Mon Jun 14 10:32:51 -0600 2010
t + (60 * 60 * 24)
=>Tue Jun 15 10:33:21 -0600 2010
I guess it has to do with the format...how do I make this work?
You're actually adding 86,400 seconds (60 seconds * 60 minutes * 24 hours).
ActiveSupport has some built in helper methods for dealing with time:
Time.now + 1.day + 15.hours
In Rails,
its very simple to use times.
r = Record.find(:first)
r.created_at + 1.day # this will give you a day to one day ahead )
r.created_at + 2.days + 15.hours + 30.minutes + 5.seconds
or use Time.now
Also, if you want take a look at the by_star plugin/gem its makes some querying etc very easy.

Resources