Create date from day, month, year as integers in KDB Q - date

I am trying to get a date from its integer components: I have day, month and year as variables (that can change, I don't want to hard code them), and I want to reunite them in a date variable.
For example, something like that;
myDay: 15
myMonth: 4
myYear: 2016
`date$(myYear,myMonth,myDay) --> should return 2016.4.15 (formatted as a date).
Any way to do that?
Thank you

q)d:3
q)m:8
q)y:2016
q)"D"$"." sv string (y;m;d)
2016.08.03
See cast vs tok - need to use different arguments depending on if what you're casting from is a string or not

Related

How to get a specific date of next month? (Java 8)

With today's date, I should get the 16th date of next month.
For example, on passing 13-12-2021, I should get 16-01-2022.
I need to get the next month 16th day from current date (input date). Examples:
On passing 13-11-2021 should get 16-12-2021.
On passing 14-11-2021 should get 16-12-2021.
On passing 15-11-2021 should get 16-12-2021.
On passing 02-12-2021 should get 16-01-2022.
On passing 03-12-2021 should get 16-01-2022.
On passing 03-01-2022 should get 16-02-2022.
On passing 04-01-2022 should get 16-02-2022.
Any help will be much appreciated. Thanks.
java.time
One of the many strong points of java.time, the modern Java date and time API, is date arithmetic like this.
public static LocalDate nthDayOfFollowingMonth(
int desiredDayOfMonth, LocalDate currentDate) {
return YearMonth.from(currentDate)
.plusMonths(1)
.atDay(desiredDayOfMonth);
}
Try it out with your example date:
System.out.println(nthDayOfFollowingMonth(
16, LocalDate.of(2021, Month.DECEMBER, 13)));
Output:
2022-01-16
We might not have needed to convert to YearMonth and back to LocalDate. Doing so relieves both me and the reader of considering what happens if today’s day of month doesn’t exist in next month — for example if current date is 30 January (there is no 30 February). What one still wants to consider is what happens if you request a day of month tht doesn’t exist next month. For example on 13 January asking for the 30th of next month. We can try that out too:
System.out.println(nthDayOfFollowingMonth(
30, LocalDate.of(2022, Month.JANUARY, 13)));
I find the result very reasonable:
java.time.DateTimeException: Invalid date 'FEBRUARY 30'

How to set day month and year values for a Date or DataAndTime object in Smalltalk (Pharo / Squeak)

I'm trying to find a a pre-defined method for objects of Class Date or Class DateAndTime, that allows me to create an new Date (or a new DateAndTime) by supplying three integers: one integer for the day of the month (1-31); one for the month (1 - 12); and a four-digit integer for the year.
( The closest I've found so far is Integer>>asYear )
Is there a method that can set all three parameters at once?
If I understand you correctly, you are trying to create an instance of Date from three integers representing the day, month and year of said date.
When facing a question like this you can browse the class, Date in this case, and check its protocol for instance creation methods. In Pharo there are several methods in this category, but it is easy so see (I think) that #year:month:day looks like a good candidate. So, you can try it. Just evaluate the expression
Date year: 2015 month: 12 day: 31
and see what happens (you can inspect or print it to see the result).
You will also find #newDay:month:year as another good candidate. You could try it too. Or you could just see that it sends our previous message and thus it is just a synonymous (which is present for compatibility with other dialects that support the Smalltalk-80/ANSI specification).
String>>asDate
allows for date-formatted Strings to be converted into Dates
e.g. (in a Workspace)
aDateString := String new . " prints as '' "
aDateString := '1984-11-03' . " prints as '1984-11-03' "
aDate := Date new . " prints as 1 January 1901 "
aDate := aDateString asDate . "prints as 3 November 1984"
The comment in the String>>asDate method states that "Many allowed forms, see Date>>#readFrom:"
Date>>readFrom: says
"Read a Date from the stream in any of the forms:
<day> <month> <year> (15 April 1982; 15-APR-82; 15.4.82; 15APR82)
<month> <day> <year> (April 15, 1982; 4/15/82)
<year>-<month>-<day> (1982-04-15) (ISO8601)"
Also relevant: String>>asDateAndTime
n.b. a DateAndTime object is an exact instant in time.
Date, Year, Month, Week and Schedule are all subclasses of Class Timespan, so they all have a start moment, a duration, and an end moment.

How can I add several months to a date coming from a date form field?

With DateJS, you'd add e.g. six months to the current date like this:
Date.today().addMonths(6);
However, I need to add 24 months not to today's date, but to a date which a user has typed into a date field. So the today() should in principle be replaced by something like this.getField('begin_date').value.
The result shall be written into another data form field.
I tried hard, but couldn't make it. Can anyone help me out?
Providing the input value is a textual representation of a date, you need to convert it into a Date object at the first place. Then you can work with it as you want.
DateJS has a pretty smart parse() function which does exactly that, so you'd achieve it like this:
Date.parse(this.getField('begin_date').value).addMonths(24)
When a specific date format is needed, like DD.MM.YYYY commonly used in Europe, you can use parseExact() and specify the format. Like this:
Date.parseExact(dateToParse, 'dd.MM.yyyy') // leading zeroes required; parses 01.04.2014 but not 1.4.2014
Date.parseExact(dateToParse, 'd.M.yyyy') // leading zeroes not required; parses both 01.04.2014 and 1.4.2014
Here is a solution that I found for my problem, using DateJS as well:
start = this.getField('begin_date').value;
var d1 = util.scand("dd.mm.yyyy", start);
var myDate = new Date(d1);
result = myDate.addMonths(24);
This works pretty fine, also spanning leap years, except for the 28th of February, 2014/2018/2022 ... ; the result then will be the 28th of February, 2016/2020/2024 ... and not the 29th of February 2016/2020/2024... In these cases it's up to the user to accept the 28th or to manually change the date to the 29th.

Joda-Time : Date calculation

I would like to calculate precisely the months between two dates to achieve this I do something like :
DateTimeZone ZONE = DateTimeZone.forID("Europe/London");
String DATE_FORMAT = "dd/MM/yyyy";
DateTimeFormatter FORMATTER = DateTimeFormat.forPattern(DATE_FORMAT).withZone(ZONE);
LocalDate dateTime = FORMATTER.parseLocalDate("28/05/2013");
LocalDate dateTime6MonthAfter = FORMATTER.parseLocalDate("28/02/2014");
Period todayUntilEndOfContract = new Period(dateTime,dateTime6MonthAfter);
todayUntilEndOfContract.getMonths() +"M/"+ todayUntilEndOfContract.getWeeks() +"W/"+ todayUntilEndOfContract.getDays() +"D/");
So this give me precisely 9 month between 28/05/2013 and 28/02/2014 BUT!!!
when I calculate the dates (29, 30, 31)/05/2013 with 28/02/2014 it always give me 9 month normally it should say 8M/3W/(6,5,4)D/ why is it always 9M/0W/0D please...?
Thanks a lot
Your issue is that you are expecting something a little different than what is provided. If I ask you the question "what is 30th January plus one month?" then there are a number of different answers which are valid under different assumptions. In Joda's case the answer is "28th February" (or 29th if a leap year).
Although you are asking for month-based information I would suggest that you obtain the number of days instead and use that as a basis, as it is probably closer to what you need:
int days = Days.daysBetween(dateTime, dateTime6MonthAfter).getDays();
You can always use this number to feed back in to your code and obtain different values to fit your requirements.

why does ColdFusion's DateDiff return strange/negative values?

Pulling my hair out again...
I need to calculate the difference between two dates in days. I'm doing this:
<cfset d = DateDiff("d", Dateformat( active_apps.app_base_coupon_start, "dd.mm.yyyy"), Dateformat( variables.useDate, "dd.mm.yyyy") )>
With active_apps.app_base_coupon_start = 27.07.2012 and variables.useDate = today = 02.10.2012.
I dumped both values, they are OK. However the dateDiff returns -168 when I was looking for (4 days in July, 31 in August, 30 in September, 2 in October) 67 days.
Question:
Can someone prevent me from losing my remaining hair and tell me what I'm doing wrong here or if there is an easier way to get the difference in days?
EDIT:
Ok, it also works like this:
<cfif DateAdd("d", active_apps.app_grace_time, Dateformat( active_apps.app_base_coupon_start, "dd.mm.yyyy") ) GT now()>
<cfdump output="e:\s\page\t\dump.txt" label="catch" var="YUP">
<cfelse>
<cfdump output="e:\s\page\t\dump.txt" label="catch" var="NOPE">
</cfif>
but I would still like to know, why dateDiff is returning strange values.
DateDiff("datepart", date1, date2) takes a datepart and two date objects as arguments.
DateFormat() as Adam Cameron already said returns a string and not a date object.
ColdFusion is trying to read "27.07.2012" and "02.10.2012" as date objects by trying to apply some known date formats. That's why "02.10.2012" is interpreted as "Feb 10 2012".
I wouldn't let ColdFusion guess the dateformat of your string. Instead you should create date objects by using CreateDate(year, month, day).
now() is also a ColdFusion date object.
First things first, dateAdd() takes DATES as arguments, not dateFormat()-ed strings. dateFormat() is for output, not for calculations.
You need to understand that just because "02.10.2012" looks like a date to you (and to me), it's not a date as far as the computer is concerned: it's a string.
Never use strings for date calculations.
In your case, CF is valiantly trying to work out what "02.10.2012" might mean as a date, and deciding it's "mm.dd.yyyy" format, which is Feb 10, whereas you mean Oct 2.
You're using an ambiguous date format. Change the DateFormat to international date format (ISO 8601) whenever you make date calculations and things will be a bit more predictable. Note that CF doesn't support every variant of the ISO format, but for the most part you just need yyyy-mm-dd which is supported.
<cfset d = DateDiff("d", Dateformat( active_apps.app_base_coupon_start, "yyyy-mm-dd"), Dateformat( variables.useDate, "yyyy-mm-dd") )>