Find the end of current month with Velocity - calendar

I've just started to use Marketo's mail scripting,
and I need to find out the last of the current month.
I could find the current date as below.How can I do further?
#set($date = $date.calendar)
#set($current_date = $date.format('yyyy-mm-dd', $date.getTime()))
$current_date
Refer to here,
Subtract months from date in velocity
I tried to subtract 1 day from the beginning of next month, but it doesn't work.
Knowing the number of days in this month is also meets the requirement.

The method you tried should work. I think that your problem is that you are overwriting $date - which initially contains the DateTool - with your working variable. When Velocity Tools org.apache.velocity.tools.userCanOverwriteTools configuration value is true (which is the default) Velocity will let you overwrite $date but the DateTool will be unavailable thereafter.
So try changing your working variable to $cal for instance. Then, you have several methods:
#set($cal = $date.calendar)
$cal.add(2, 1)
$cal.set(5, 1)
$cal.add(5, -1)
$date.format('yyyy-MM-dd', $cal)
or
#set($cal = $date.calendar)
$cal.set(5, $cal.getActualMaximum(5))
$date.format('yyyy-MM-dd', $cal)
In all cases, you resort to using the Calendar.MONTH and Calendar.DATE constants (respectively 2 and 5). You may want to put such utility operations in a Java tool of your own to have more readable templates.

Related

How should I dynamically query the data per month?

I'll be using reactjs and chartjs to create this. Though I do not have the codes yet, I would only like to ask for advice or to have a better understanding before coding it. In firestore, I already have this data:
I wanted to dynamically query it per vaccine and per month. What I somewhat thought of to do was to have a selection for the user to choose what year and what type of vaccine. I kind of thought of these codes however, dynamically querying it per month was quite difficult:
the selectedVaccine - is the variabale for the select where users can choose what type of vaccine.
db.collection("users") .where("doses.selectedVaccine","==", selectedVaccine) .where("doses.firstDose","==", true)
Any advice would be appreciated about querying it per month. Thank you.
db.collection("users")
.where("doses.selectedVaccine","==", selectedVaccine)
.where("doses.firstDose","==", true)
.where("doses.firstDose", ">=" start)
.where("doses.firstDose", "<" end);
// change doses.firstDose to whichever date you want to use.
For any start and end date (e.g 1st Jan 2020 and 31st Dec 2020), the above query should return all first doses within that time frame.
Then you can loop through the results and place them in arrays depending on their months. Array of all Januaries first doses in position 0, Array of all Februaries first doses in position 1 etc.
This will involve downloading the full data of all doses for a year. If your intention is just to plot a chart, then consider this solution

How to display data in area chart starting from the year chosen on a slicer and get all following years in Power BI

When choose a single Year on slicer I want area chart display all data from that chosen year and till the end (all years I have in my datasource).
But instead it just displays me the data for single year choosing on a slicer.
So I have this:
But I want it look like this: whatever Year I choose in slicer - chart will show all data starting from 2014 and goes till 2017.
I am simply following a PowerBI template example and it seems like it's possible to do that:
https://app.powerbi.com/view?r=eyJrIjoiMjc2NzExODItMjNhYy00ZWMxLWI2NGItYjFiNWMzYzUzMzhlIiwidCI6IjU3NGMzZTU2LTQ5MjQtNDAwNC1hZDFhLWQ4NDI3ZTdkYjI0MSIsImMiOjZ9
This is doable but it requires some tricks and extra measures.
TL;DR: The slicer you see is actually served as a value picker, not as a filter. An extra measure based on the value is created and used as visual level filter for the visual to do the trick.
If you want to follow along, you can download the .pbix file from this Microsoft edX course about Power BI.
First, create a new table based on the existing Date table, with only distinct years:
Year = DISTINCT('Date'[Year])
Then, create a slicer with the Year column from the newly created Year table (NOT the Date table).
A measure (used as flag) is created as follows:
Flag =
VAR YearSelected = FIRSTNONBLANK(VALUES('Year'[Year]), 0)
RETURN
IF(VALUES('Date'[Year]) >= YearSelected, 1, 0)
So basically it gets the year selected from the year slicer and compare it with the year value in the date table to see if it's greater than or equal to it.
The chart is created with Year column from the Date table (NOT the Year table), and other needed measures. Flag is added to the Visual level filters and set to 1.
So the Flag value will change according to the value picked in the Year slicer, and served as the actual filter to the chart displayed.
Results:
EDIT: on more use cases
#Oleg Try to think of how you can apply the Flag concept further. For example, if you want another chart displaying data of the same year as the slicer, you can set up another flag called SameYearFlag and only change the part of value comparison to =. Add it to the chart Visual level filter and it'll show only data in the same year. Yes, by extension, that means you can have another flags like LastYearFlag, NextYearFlag, etc, as long as it makes sense to you. The use case is up to you.
LastYearFlag =
VAR YearSelected = FIRSTNONBLANK(VALUES('Year'[Year]), 0)
RETURN
IF(YearSelected - VALUES('Date'[Year]) = 1, 1, 0)
NextYearFlag =
VAR YearSelected = FIRSTNONBLANK(VALUES('Year'[Year]), 0)
RETURN
IF(VALUES('Date'[Year]) - YearSelected = 1, 1, 0)
SameYearFlag =
VAR YearSelected = FIRSTNONBLANK(VALUES('Year'[Year]), 0)
RETURN
IF(VALUES('Date'[Year]) = YearSelected, 1, 0)
Examples:
By having only one year slicer, I can have charts with data in the same year, last year, next year and all years following, by applying different flags to them.
As said, it's up to you to come up with more interesting use cases!
I would propose to consider the new numeric range slicer.
You can just set it as "Greater than or equal to". Users can select then the initial year in the range by entering the number or dragging the slicer.
You would need to enable this feature in Power Bi Desktop, Options under "Preview features".
Is well presented in the documentation https://powerbi.microsoft.com/en-us/documentation/powerbi-desktop-slicer-numeric-range/
This is how it could look like:

Add efficiently 1 month to current date in CakePHP 2.x

What is the best way to add an expiry date in CakePHP?
I've got an "expiry date" column in my database, I want to add 1 month to the current date, and store this. At the moment, I'm just using strings and plain PHP date functions to create a new date string to save:
$date = date("Y-m-d");
$date = strtotime(date("Y-m-d", strtotime($date)) . " +31 days");
$this->data['Access']['expires'] = $date;
Is there a "more CakePHP" way or efficient/performance wise?
Performance wise we're most probably talking about micro optimizations at best, so that probably shouldn't be your main concern. However, all the back and forth that you're doing there doesn't make much sense, a single call to strtotime() is all you need, ie
$this->data['Access']['expires'] = strtotime('+31 days');
This will result in a timestamp of "now + 31 days".
The Cake-ish way would be to use the CakeTime class, for example CakeTime::fromString(), like
App::uses('CakeTime', 'Utility');
$this->data['Access']['expires'] = CakeTime::fromString('+31 days');
When passing a string (it also accepts integers and \DateTime instances), this is basically just a wrapper for strtotime(), and an additional mechanism that incorporates the timezone set for your application, so while this will be a little bit slower of course, it might still be wise to use it.
See also
Cookbook > Core Libraries > Utilities > CakeTime
Better that adding 31 days is better to use 1 months this will add 30 or 31 days depending on which month will be the current date
$dateAfterOneMonth = date('Y-m-d H:i:s', CakeTime::fromString('+1 months'))

Orbeon calendar behavior

when using a calendar (input with a bind to a date), is there a way to control the interpretation of the input ?
For what I've seen:
1-31 will be the nth of the current month
32-99 is n day after the first of the current month
x0y is the yth day of xth month of the current year
Then it's a little random
511950 will give 05/01/2050
but 151950 will give 01/05/2050
From what i gathered, the control tries to interpret some symbols (any symbol, this includes digits) as separators.
So for example, 151950 is 1/1/50 instead of 1/5/1950 and because it's more than 50 years, the '50' is translated as 2050 instead of 1950.
This is pretty confusing for users, specially when they explicitly put the year with 4 digits and not only 2.
So i'm looking for a way to be a lot stricter. For instance only allowing the dd/mm/yyyy format (with explicit separators). The rest would render the value invalid instead of trying to translate it in something it is not.
Is there a way to do that ?
We're using Orbeon 3.8, and our forms are mostly in french, so dd/mm order.
The parsing is done with regular expressions. See the code here. (To be fair: this code is old!)
I suspect that the overflow conditions are simply a product of the JavaScript date object.
The only way to change this behavior as far as I know is to change the JavaScript code.

How to loop through a range of week status variables in SAS and pull status according to specific week given by other variable

I have a range of weekly variables describing a person's "status" (from week 1, 2010 to 2012 week 17).
The variables are given by:
y_1001, y_1002,...y1052, y1101, y1102,......y_1217
I define the period of variables like this:
%let period = y_1001-1052 y_1101-y1148;
I also have a treatment period given as a start date and an end date. My challenge is to find the status given by the y_ variables in the week after the person stops the treatment.
I am not too familiar with SAS, but my idea was to "pick" the correct y_ variable based on a week counter, say by counting the number of weeks since the beginning of the period (week 1 in 2010) and until the date where the treatment ends.
I get the weeks until end of treatment like this
week_count = 1 + intck( 'week.2', '1JAN2010'd, end_treatment_date, 'd');
But how can I retrieve the corresponding y_ variable based on this count?
After fruitless search on how to loop over the period variables and pick the number corresponding to the week_count variable for each person, I thought about going a different way... say something like this.
array weeks(*) &period;
do i = 1 to dim(weeks) by 1;
if week_count = i then end_status = y_10&i;
end
...but with modifications to take into account that there is a mismatch between the dimension of the array and the number of weeks and years.
But then my challenge is to make the following part work...
if week_count = i then end_status = y_10&i;
How can I make SAS pick the right y_ variable based on the loop index? This seems like a really simple problem, but somehow I have not managed to find a solution. Is there no way to use the variable "i" as input in defining the correct y_ variable?
Would really appreciate if somebody could throw some hints.
I think you want:
if week_count = i then end_status = weeks{i};
VVALUEX is a little known function in SAS which can help you to extract a value from a SAS variable name. Here your problem is to construct the SAS variable name given the number of weeks from the 1st Jan to the end of treatment. You can avoid using a DO LOOP for every observation by using the ideas in the example below -
data _null_;
end_treatment_date = "09FEB2010"d;
y_1007 = 'D';
status = vvaluex(compress("y_" || substr(strip(year(end_treatment_date)), 3, 2) || put(1 + intck("week.2", "01JAN2010"d, end_treatment_date), z2.)));
put status;
run;
The variable name is constructed as follows - initally you take the string "y_" and then append the last two digits of the year followed by the week using similar logic to your variable week_count as before. You get the variable you want, and then apply VVALUEX to get the value. Running the DO LOOP for every observation can be inefficient if you have millions of them.

Resources