How to compare two dates with current date in Tibco BW? - tibco

For Example, if you have a date coming from Start activity, How can we compare that date with current date?

There actually a function present exactly for that purpose. It is called compare-date or compare-dateTime (if time is also relevant).
The signature of this function is:
compare-date('1980-08-05','1980-09-04')
returns -1 if first
returns 1 if second
return 0 if both are equal.
In your case this could mean something like:
compare-date($Start/root/Date,current-date())

You can do in following way:
Take two mappers for example, for first use two inputs and give following xpath in an order:
1.For current Date :
tib:parse-date("yyyyMMdd",tib:format-date("yyyyMMdd",current-date()))
For Start Input
tib:parse-date("yyyy-MM-dd", $Start/root/Date)
and compare it in somewhere in your End's Input like:
if ($parseDate/root/currentdate= $parseDate/root/rDate) then substring(
$parseDate/root/currentdate - $parseDate/root/Date, 3,
string-length(($parseDate/root/currentdate - $parseDate/root/Date))-3) else
substring( $parseDate/root/currentdate - $parseDate/root/Date,2,
string-length(($parseDate/root/currentdate - $parseDate/root/Date))-2)

Related

How to format thousands from digit a with a point

I'am looking for the best way to format thousands from digit a with a point. I am creating a view from an other table and I need for some columns to have this type of format.
ex : 10000 -> 10.000
Thank you in advance for your possible answers !
There is way how to do it without UDF but it can be performance issue. But for small sets of data it works:
You can use the following combination of build-in functions:
// Template
select reverse(concat_ws(".",split(reverse(<column-to-format>),"(?<=\\G.{3})")));
// sample 1 - format number 12345678
select reverse(concat_ws(".",split(reverse("12345678"),"(?<=\\G.{3})")));
// sample 2 - format number 10000
select reverse(concat_ws(".",split(reverse("10000"),"(?<=\\G.{3})")));
Explanation for sample 1 with number 12345678
1. reverse("12345678") Result: 87654321
2. split(reverse("12345678"),"(?<=\\G.{3})")")) Result: array [876,543,21]
3. concat_ws(".",split(reverse("10000"),"(?<=\\G.{3})")) Result "876.543.21"
4. finally reverse it back. Result: "12.543.876"

Check if a value is less than any value of an array

I have a time-stamp '2016-02-08 16:23:53' and an array containing different time-stamps ['2016-02-09 14:23:53', '2015-02-08 16:23:53', '2016-02-08 16:22:53'].
What is the simplest way to check if the value is less than any of the value in array and return true or false?
If timestamps are strings:
['2016-02-09 14:23:53', '2015-02-08 16:23:53', '2016-02-08 16:22:53'].none? do |ts|
Time.parse(ts) > Time.parse('2016-02-08 16:23:53')
end
If timestamps are already instances of Time, there is no need for parse:
timestamps_array.none? do |ts|
ts > Time.parse('2016-02-08 16:23:53')
end
Well, for the sake of #sawa’s patience :)
It is inefficient to parse the value to compare against each time in the loop:
timestamp_to_check = Time.parse('2016-02-08 16:23:53')
['2016-02-09 14:23:53', '2015-02-08 16:23:53', '2016-02-08 16:22:53'].none? do |ts|
Time.parse(ts) > timestamp_to_check
end
Checking if a value is less than any value in an array may be accomplished in Ruby with
value < array_of_values.min
The simplest way to solve the example given by the OP is
'2016-02-08 16:23:53' < ['2016-02-09 14:23:53',
'2015-02-08 16:23:53',
'2016-02-08 16:22:53'].min
Comparing string representations of dates and times will only work if all strings involved use the same format, the numbers are ordered from big to small (years down to seconds), and the numbers use leading zeros.
The use of adequate data types (like Time or DateTime) instead of strings for storing and processing dates and times will improve the robustness of the software.

How to write dates (MM/DD/YY) into a matrix (SAS)

I have following problem:
I need to write a begin and end date into a matrix. Where the matrix contains the yearly quarters (1-4) in the collumns and the rows are the year.
E.g.
Matrix:
Q1 Q2 Q3 Q4
2010
2011
Now the Date 01.01.2010 should be put in the first element and the date 09.20.2011 in the sixed element.
Thanks in advance.
You first have to consider that SAS does not actually have date/time/datetime variables. It just uses numeric variables formatted as date/time/datetime. The actual value being:
days since 1/1/1960 for dates
seconds since 00:00 for times
seconds since 1/1/1960 00:00 for datetimes
SAS does not even distinguish between integer and float numeric types. So a date value can contain a fractional part.
What you do or can do with a SAS numeric variable is completely up to you, and mostly depends on the format you apply. You could mistakenly format a variable containing a date value with a datetime format... or even with a currency format... SAS won't notice or complain.
You also have to consider that SAS does not even actually have matrixes and arrays. It does provide a way to simulate their use to read and write to dataset variables.
That said, SAS does provide a whole lot of formats and informats that allow you to implement date and time manipulation.
Assuming you are coding within a data step, and assuming the "dates" are in dataset numeric variables, then the PUT function can extract the datepart you need to calculate row, column of the matrix element to write to, like so:
DATA table;
ARRAY dm{2,4} dm_r1c1-dm_r1c4 dm_r2c1-dm_r2c4;
beg_row = PUT(beg_date, YEAR4.)-2009;
end_row = PUT(end_date, YEAR4.)-2009;
beg_col = PUT(beg_date, QTR1.);
end_col = PUT(end_date, QTR1.);
dm{beg_row,beg_col} = beg_date;
dm{end_row,end_col} = end_date;
RUN;
... or if you are using a one-dimensional array:
DATA table;
ARRAY da{8} da_1-da_8;
beg_index = 4 * (PUT(beg_date, YEAR4.)-2010) + PUT(beg_date, QTR1.);
end_index = 4 * (PUT(end_date, YEAR4.)-2010) + PUT(end_date, QTR1.);
da{beg_index} = beg_date;
da{end_index} = end_date;
RUN;

How can I select the second last item in a xpath query?

I'm new to xpath and I understand how to get a range of values in xpath:
/bookstore/book[position()>=2 and position()<=10]
but in my case, I need to get above 2 and one less then the total(so if there's 10 then I need 9, or if there's 5, I need up to the 4th spot). I'm applying my code to different pages and the number of entries is not always the same.
In python, I could do something like book[2:-2], but I'm unsure if I can do this within xpath.
You can use last() which represents the last item in the context:
/bookstore/book[position()>=2 and position() <= (last() - 1)]
In my case this was working for me to get last but one element
/bookstore/book[position() = (last() - 1)]

ruby / rails - hash max by :key does not return largest value

I have a query that looks for all events on a given date #s_date. Event start_datetime is within day OR - event end_datetime is within day
#s_hash_items = #company.events.where('(start_datetime > ? AND start_datetime < ?) OR
(end_datetime > ? AND end_datetime < ?)',
#s_date.beginning_of_day, #s_date.end_of_day,
#s_date.beginning_of_day, #s_date.end_of_day)
I am then trying to find the latest end_datetime value from this array. E.g. there are 3 events finishing at 14:00, 17:30 and 15:00, I want to return 17:30. But, if there is an event that runs over to the next day, I want the max result to be 23:59:59 on #s_date).
My code to do that looks like this
#s_end_hour = [#s_hash_items2.max_by{:end_datetime}.end_datetime, Time.now.end_of_day].sort.first.hour
So it produces an array with latest end date time, and end of day, and picks out whichever one is earlier (sort.first), then returns the hour number, e.g. 17 in this case.
However, the max_by method is not finding the event with the latest end_datetime. It seems to vary depending on the order of the #s_hash_items result. But the order of #s_hash_items shouldn't matter - I just want the max value. What am I doing wrong here? Thanks.
This doesn't do what you think it does:
#s_hash_items2.max_by{:end_datetime}
That's same as saying:
#s_hash_items2.max_by { 11 }
i.e. you're asking max_by to find the element with maximum :end_datetime Symbol (a constant value) and that's a bit pointless.
If you want max_by to call the end_datetime method then you want a block that returns the the end_datetime value of the objects:
#s_hash_items2.max_by { |item| item.end_datetime }
or more concisely (and probably what you were trying to say):
#s_hash_items2.max_by(&:end_datetime)
The & more or less turns the symbol into the { |item| item.end_datetime } block in the first previous example.

Resources