In Pig Latin, is there a built-in function to find the Month End date for a given date ? For example, if the given date is '2015-03-15', the month end date returned should be '2015-03-31' and if given date is '2015-04-15', the month end date should be '2015-04-30'.
This is how you do it:
REGISTER /usr/lib/pig/piggybank.jar;
DEFINE ISOToMonth org.apache.pig.piggybank.evaluation.datetime.truncate.ISOToMonth();
%declare END_OF_MONTH SubtractDuration(AddDuration(ToDate(ISOToMonth('2015-03-15')),'P1M'),'P1D')
A = LOAD 'DummyFileWithOneRow.txt' USING PigStorage(',') AS (f1:chararray, f2:chararray);
result = FOREACH A GENERATE
f1 AS f1,
$END_OF_MONTH AS end_of_month;
DUMP result
The result of this run is:
(1,2015-03-31T00:00:00.000Z).
You can now convert this result to your desired format.
You can do this calculation as part of the foreach on the loaded values.
The ordinary way to do such things, if you do not find that the language in question already has a built-in set of functions to "do such things," is to ... in this case:
Determine the first day of the current month. ("Month/01/Year" This is the only step that you "do by hand.")
Add "one month" to that. (There should be some kind of "DateAdd()" function in your language...)
Finally, using the same function, "subtract one day."
December 15th => December 1st => January 1st (of next year) => December 31st (of this year).
But first, look carefully. "Accountants want to do this sort of thing all the time." There is usually a pretty-good, sometimes very-good, set of functions to do date-manipulation. (And if they're not built-in to the language, there's often a contributed library of "goodies" that someone else already wrote and perfected.)
Related
I've looked for help on the internet for the following, but I could not find a satisfying answer: for an assignment, I need to plot the time series of a certain variable (the term spread in percentages), with years on the x-axis.
However, we use daily data. Does anybody know a convenient way in which this can be done? The 'date' variable that I've got is formulated in the following way: 20111017 represents the 17th of October 2011.
I tried to extract the first 4 numbers of the variable 'date', by using the substr(date, 1, 4) command, but the message 'type mismatch' popped up. Also, I'm not quite sure if it gives the right information if I only use the years to plot daily data (over the years). It now gives the following graph, which doesn't look that nice.
Answering the question in your title.
The date() function expects a string. If your variable with value 20111017 is in a numeric format you can convert it like this: tostring datenum , gen(datestr).
Then when using the date() function you must provide a mask that tells Stata what format the date string is in. Below is a reproducible example you can run to see how this works.
* Example generated by -dataex-. For more info, type help dataex
clear
input float datenum
20111016
end
* Convert numberic varaible to string
tostring datenum , gen(datestr)
* Convert string to date
gen date = date(datestr, "YMD")
* Display date as date
format date %td
If this does not help you, try to provide a reproducible example.
This adds some details to the helpful answer by #TheIceBear.
As he indicates, one way to get a Stata daily date from your run-together date variable is convert it to a string first. But tostring is just one way to do that and not essential. (I have nothing against tostring, as its original author, but it is better suited to other tasks.)
Here I use daily() not date(): the results are identical, but it's a good idea to use daily(): date() is all too often misunderstood as a generic date function, whereas all it does is produce daily dates (or missings).
To get a numeric year variable, just divide by 10000 and round down. You could convert to a string, extract the first 4 characters, and then convert to numeric, but that's more operations.
clear
set obs 1
gen long date = 20111017
format date %8.0f
gen ddate = daily(strofreal(date, "%8.0f"), "YMD")
format %td ddate
gen year = floor(date/10000)
list
+-----------------------------+
| date ddate year |
|-----------------------------|
1. | 20111017 17oct2011 2011 |
+-----------------------------+
I have just started to code in Prolog, and I cannot do what I would like to.
Basically I have 2 input: a start date "2018/02/14" and a duration "99 days/months". I would like to know if there would be a way to predict the end date from this, in PROLOG:
date(X,Y,Z):-is_a_date(X),is_a_duration(Y),...
The main problem is about date format...
Any tips ?
The main problem is about date format...
Prolog uses terms to model data. Terms can be atoms or numbers, or any compound terms obtained by applying functors or operators to other terms. / is an operator. So 2018/02/14 is a perfectly fine Prolog term:
?- Date = 2018/02/14.
Date = 2018/2/14.
This is different from most other programming languages, in which something like the above would be an expression that would be evaluated to a value. For example, entering 2018/2/14 into a Python prompt gives back 72.0714 because it thinks we want it to compute a number. But in Prolog the example above is not asking for a number; it simply says that 2018/02/14 is some data made up of three numbers separated by / signs.
To operate on Prolog data structures, we use unification:
?- Date = 2018/02/14, Date = Year/Month/Day.
Date = 2018/2/14,
Year = 2018,
Month = 2,
Day = 14.
We unified the date with another, similar term Year/Month/Day. Here, the leaves of the term are variables. Unification will bind these variables to the numbers in the date terms at the corresponding positions. That is all!
So (using meaningful variable and predicate names, which are very important in Prolog) you can write your predicate as:
startdate_duration_enddate(Year/Month/Day, Duration, EndDate) :-
... .
What is the command for displaying the time and date in qbasic? Could the syntax for the commands be given as well? And an explanation if possible?
You can use DATE$ and TIME$
These can also set the date and time as well.
The command for printing the time(current system time) is time$
The time$ is actually a function, in this case, no parameter is needed.
And the code is...
PRINT TIME$
The time is printed in hh: mm: ss format(hour: minutes: seconds).
And therefore the output would be something like this:
14:55:28
For printing the current system date, we use date$ function which is also a string function
The code is:
PRINT DATE$
The date is printed in mm-dd-yyyy format or month-day-year(American date format).
Hence the output will be:
02-17-2018
Hope it helps...
The QB date/time functions are:
DATE$ returns the date in a string in the form MM-DD-YYYY
TIME$ returns the time in a string in the form HH:MM:SS
When used as a command the date$ and time$ can be assigned to set the system date and time, for example DATE$ = "12-10-1990" or TIME$ = "12:10:10"
If the year is a leap year then the 29th day of February could be set. Otherwise if it is not a leap year then a syntax error will occur trying to set the date in February to the 29th.
I want to assign the current year in a YY format to either a macro or data set variable.
I am able to use the automatic macro variables &sysdate or &sysdate9 to get the current date. However, extracting the year in a YY format is proving to be a nightmare. Below are some examples of what I've been trying.
There exists the YEARw. format. But when I try to use it I get errors or weird results. For instance, running
data _null_;
yy = year(input("&sysdate9.", year2.));
put yy=;
run;
produces the error
ERROR 48-59: The informat YEAR was not found or could not be loaded.
If I try to format the variable in the output, I get 1965 instead of the current year. The following
data _null_;
yy = year(input("&sysdate9.", date9.));
put yy= yy year2.;
run;
outputs
yy=2016 65
Please help.
This works to get you the 2-digit year number of the current year:
DATA _NULL_;
YEAR = PUT(TODAY(),YEAR2.);
PUT YEAR;
RUN;
/* Returns: 16 */
To breakdown what I am doing here:
I use TODAY() to get the current date as a DATE type. &SASDATE needs to be converted to a DATE, but also it is the date that the SAS session started. TODAY() is the current date.
PUT allows us to pass in a non-character (numeric/date) value, which is why it is used with TODAY() as opposed to INPUT.
I think it is worth exploring the issues here in more detail.
First, Formats are patterns for converting numeric values to a human readable format. That's what you want to do here: convert a date value to a human readable format, in this case to a year.
Informats, on the other hand, convert human readable information to numeric values. That's not what you're doing here; you have a value already.
Second, put matches with Formats, and input matches with informats, exclusively.
Third, you get close in your last try: but you misuse the year format. Formats are basically value mappings, so they map every possible numeric value in their range (sometimes "all values" is the range, sometimes not) to a display value (string). You need to know what kind of value is expected on the input. YEARw. expects a date value as input, not a year value: meaning input is "number of days from 1/1/1960", mapped to "year". So you cannot take a value you've already mapped to a year value and map it again with that method; it will not make any sense.
Let's look at it:
data _null_;
yy = year(input("&sysdate9.", date9.));
put yy= yy year2.;
run;
yy contains the result of the year function - 2016. Good so far. Now, you need the 2 digit year (16); you can get that through mod function, if you like, or put/substr/input:
data _null_;
yy = input(substr(put(year(input("&sysdate9.", date9.)),4.),3,2),2.);
put yy=;
run;
mod is probably easier though since it's a number. But of course you could've used year:
data _null_;
yy = put(input("&sysdate9.", date9.),year2.);
put yy=;
run;
Now, yy is character, so you could wrap that with input(...,2.) or leave it character depending on your purposes.
Finally - a use note on &sysdate9.. You can easily make this a date without input:
"&sysdate9."d
So:
yy = put("&sysdate9."d,year2.);
That's called a date literal (and "..."dt and "..."t also work for datetime,time). They require things in the standard SAS formats to work properly.
And as pointed out in Nicarus' answer, today() is a bit better than &sysdate9 since it is guaranteed to be today. If you're running this in batch or restart your session daily, this won't matter, but it will if you have a long-running session.
Apply the year function to the date variable
Convert to string
Take last 2 digits
EDIT: change input to PUT
Year = substr(put(year(today()), 4.), 3);
I'm trying to insert date field in MS Word that will display tomorrow's date we one opens the document.
I can insert Today's date {DATE \# "dd/MM/yyyy"}, can we insert tomorrow's date using modified formula?
Thanks
Without VBA, the calculation is possible, but not straightforward, because the Word field language has very limited support for date-related operations.
Originally I thought Word would auto-update the DATE when you open or close/re-open the document, but further experiments suggest that even the second suggestion in here will not do that.
In the specific case described (add 1 day), you should be able to use the following field coding:
{QUOTE {SET xxx { DATE }}{SET yyy {xxx \#YYYY}}{SET mmm {xxx \#M}}{SET xxx1 {={xxx \#YYYYMMDD}+1 \#0000'-'00'-'00}}{=13-{xxx1 \#M} \#"'{xxx1}';'{=mmm-11 \#'{=yyy+1}-01-01';'{yyy}-{=mmm+1 \#00'-01'}'"}'"} \#DD/MM/YYYY}
All the {} must be the special field code brace pairs that you can insert on Windows Word using ctrl-F9, and (typically) on Mac Word using cmd-F9 or fn-cmd-F9, depending on your keyboard setup. You can change the format at the end ("\#DD/MM/YYYY" ) as required.
However, that set of field codes probably will not be updated automatically by Word when you open the document, so the user would need to select the field codes and press F9.
I originally thought Word would update the date on open and/or close/re-open using the following coding, but I now believe I was wrong. The one thing it does achieve on recent versions of Windows Word is to present the Date field in a "bubble" with an option to update the field:
{DATE \#"'{QUOTE {SET xxx { DATE }}{SET yyy {xxx \#YYYY}}{SET mmm {xxx \#M}}{SET xxx1 {={xxx \#YYYYMMDD}+1 \#0000'-'00'-'00}}{=13-{xxx1 \#M} \#"'{xxx1}';'{=mmm-11 \#'{=yyy+1}-01-01';'{yyy}-{=mmm+1 \#00'-01'}'"}'"} \#DD/MM/YYYY}'"}
Here is some pseudocode for the algorithm:
Set xxx to the date.
Set yyy to the 4-digit year
Set mmm to the month
Set xxx1 to the date but with the day number incremented by 1. e.g., for 2016-12-31, that would be a string, "2106-12-32"
This is the tricky bit:
Try to extract the month from that date using { xxx1 \#M }. If the date is valid, { xxx1 \#M } will return a valid month number, i.e. in the range 1 to 12. If the date is not valid, { xxx1 \#M } will return xxx1, e.g. "2106-12-32", which the { = } field will treat as a calculation, i.e. "year-(a maximum of 12+32=44)", so it is always going to return a number larger than 12.
If xxx1 is a valid date then
result=xxx1
Else 'xxx1 is not a valid date so...
If mmm (the original month) is 12 then
result = "(yyy+1)-01-01"
Else
result = "yyy-(mmm+1)-01"
End If
End If
Apply the date format you want to "result".
NB, this also relies on the assumption that Word always correctly recognises the month and day when you specify a date in the format "YYYY-MM-DD", regardless of the locale, in other words that "2016-04-01" is always recognised as 01 April 2016, never as 04 January 2016. If anyone can provide a counter-example, then the assumption is wrong, the field coding will need to change, and will probably need to be locale-dependent.