get number of days in month with time4j - java

Is there a way to get number of days in a month using time4j lib?
in android default calendar, we can get it so simple like below
Calendar calendar=Calendar.getInstance();
int numOfDaysInMonth=calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
I mean a standard way, not crazy ways like going to the first Day of next month then come back one day and get day of month.
so can we do that in time4j calendars like "PersianCalendar"

The answer of #محمد علی using the default maximum has a problem: It does not use any calendar context so the maximum in leap years cannot be determined for the last month ESFAND. But the old comment given by #Tunaki is already a good and simple answer:
PersianCalendar today = PersianCalendar.nowInSystemTime();
int lengthOfCurrentMonth = today.lengthOfMonth();
Alternatively, you can also use the element PersianCalendar.DAY_OF_MONTH but then you should determine the contextual maximum, not the default maximum:
PersianCalendar today = PersianCalendar.nowInSystemTime();
int lengthOfCurrentMonth = today.getMaximum(PersianCalendar.DAY_OF_MONTH);
Both expressions will yield the same results in all ways and are completely equivalent.
For standard months (FARVARDIN (1) until BAHMAN (11)) the results will agree with the default maximum. But the last month ESFAND has either 29 days in normal years or 30 days in leap years. Both methods presented here will take this into account (but not the default maximum method).

Related

Is there a way to correctly count number of days in 1582

How would one calculate a number of days in 1582. Yes, that is the year of introduction of the Georgian Calendar (in some countries). I assume October 1582 should not have 31 days as some of the dates never existed.
Yet when I tried Joda Time (Java/Groovy) it says 30 days:
LocalDate start = new LocalDate("1582-10-01");
LocalDate end = new LocalDate("1582-10-31");
println Days.daysBetween(start, end).getDays();
Same for SQL
-- PostgreSQL
SELECT DATE_PART('day', '1582-10-31'::date - '1582-10-01'::timestamp);
-- MSSQL
SELECT DATEDIFF(dd, '1582-10-31', '1582-10-01');
So is there some agreement/specification to actually treat 1582-10-14 as if it would actually exist? Or is there some easy way to calculate correct diff for year 1582 and earlier?
I have not used Java in many years, but I am familiar with dealing with several calendars in other languages. From the "Key Concepts" subtab of the "Documentation" tab of the Joda Time website we find the "Chronology" page which states
The default chronology in Joda-Time is ISO. This calendar system is
the same as that used by business in the majority of the world today.
The ISO system is unsuitable for historical work before 1583 as it
applies the leap year rules from today back in time (it is a proleptic
calendar). As a result, users requiring a more historically accurate
calendar system are forced to think about their actual requirements,
which we believe is a Good Thing.
Proleptic means that from a known day and date that virtually everyone agrees about, such as the Meter Convention having been signed in Paris on 20 May 1875, the rules of the calendar are applied backward to find any date desired, even if it is before the calendar was created.
As for computing the interval in one calendar, such as the Julian calendar, to a date in a different calendar, such as the Gregorian calendar, a common approach is to convert them both to a count-of-days from a chosen epoch, such as the modified julian date, which counts from midnight universal time at the beginning of November 17, 1858. Then one simply subtracts one day count from the other to find the number of days between them. A quick glance at the Joda Time documentation did not show any facility for computing a day count.
I am currently not set up to program in Java. Ole V.V. comment about using the Gregorian-Julian chronology of Joda-Time seems useful, but I have not tried it:
LocalDate first = new LocalDate(1582, 10, 1, GJChronology.getInstance());
LocalDate last = new LocalDate(1582, 10, 31, GJChronology.getInstance());
int countOfDaysDiff = Days.daysBetween(first, last).getDays();
System.out.println(countOfDaysDiff);
Output according to Ole V.V.:
20
I think I will go ahead and close with that both answers are probably correct. October 1582 did and didn't have 31 days. I mean that 14th October didn't exist (as in no one was born on that day in Gregorian Calendar) and for the purpose of accounting all debts were pushed by ten days. So I guess the only way is to manually count days and don't use any libraries for that.
When establishing Gregorian Calendar it was said that:
we direct and ordain:
that ten days shall be removed from the month of October of the year 1582
But also:
But in order that nobody suffers prejudice by this our subtraction of ten days, in connection with any annual or monthly payments, the judges in any controversies that may arise over this, shall by reason of the said subtraction add ten days to the due date for any such payment.
Source: https://en.wikisource.org/wiki/Translation:Inter_gravissimas

A Bug in java time calculating months between 2 dates

When using java.time in Scala I experienced a strange behavior. I want to calculate the number of months between two dates like this:
import java.time._
Period.between(LocalDate.parse("2015-03-31"), LocalDate.parse("2015-04-30"))
// java.time.Period = P30D
// I would expect java.time.Period = P1M
Period.between(LocalDate.parse("2015-03-31"), LocalDate.parse("2015-05-01"))
// java.time.Period = P1M1D
Is this a bug or do I have got it all wrong?
org.joda.time works as I would expect it:
import org.joda.time.DateTime
import org.joda.time.Months
Months.monthsBetween( new DateTime().withDate(2015, 3, 31), new DateTime().withDate(2015, 4, 30))
//org.joda.time.Months = P1M
When adding months to a java.time.LocalDate it works fine:
java.time.LocalDate.parse("2015-03-31").plusMonths(1)
// java.time.LocalDate = 2015-04-30
This is not a bug, and it is behaving like expected (see also JDK-8152384 and JDK-8037392, which were closed as "Not An Issue"). Joda Time and the Java Time API have different behaviour regarding this. Quoting Stephen Colebourne from the previous bug report:
The OP appears to want a rule where the days are calculated based on the original month length, not the one that results once the month-year difference is applied. The OP is not wrong, its just that its not how we choose to make the calculation in java.time.
Indeed, from Period.between:
The period is calculated by removing complete months, then calculating the remaining number of days, adjusting to ensure that both have the same sign. [...] A month is considered to be complete if the end day-of-month is greater than or equal to the start day-of-month.
Between the 31st of March, and the 30th of April, no complete month has elapsed. As such, you have a period containing the number of days between the two dates, which is 30. To have the complete month of April elapsed, you need to add one day to the end date, and make it the 1st of June.
Joda has a different way of calculating the month period. From Months.monthsBetween:
This method calculates by adding months to the start date until the result is past the end date. As such, a period from the end of a "long" month to the end of a "short" month is counted as a whole month.
Joda explicitly takes the variable number of days in a month into account when calculating the number of months between the two dates. Java Time doesn't.
I agree that it is a bit unexpected, but it is the correct result if you take into account the javadoc.
From the javadoc
The start date is included, but the end date is not. The period is calculated by removing complete months, then calculating the remaining number of days, adjusting to ensure that both have the same sign. The number of months is then split into years and months based on a 12 month year. A month is considered if the end day-of-month is greater than or equal to the start day-of-month. For example, from 2010-01-15 to 2011-03-18 is one year, two months and three days.
The difference comes from what a "complete month" means.
In this case 1st April to 1st May (exclusive) is considered a complete month while 31st March to 30th April (exclusive) is not.
I believe the Period.between is returning P30D in the first example because the second parameter is exclusive. This is according to https://docs.oracle.com/javase/8/docs/api/java/time/Period.html#between-java.time.LocalDate-java.time.LocalDate-
public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)

How to calculate sequential (ordinal) number of a specific weekday in a month in Java

I am trying to determine the sequential ordinal number of a weekday in a month in Java. i.e. if a Friday is the first or 3rd friday of a month.
I can not find a simple way after reading all the things I can find on Java Calendar and posts here. One way I can think of is to determine how many days the first week of this month have in this month and then adjust week_of_month based on what day the day in question is. However, it requires a little complicated calculation. Anyone knows a simple solution?
Just take the day of month, subtract 1, divide by 7, then add 1. The first seven days of the month are always the first (Tuesday, Wednesday, ...) whatever day of the week the actual 1st of the month is.
Personally I'd use Joda Time:
public int getWeekOfWeekDay(LocalDate date) {
return ((date.getDayOfMonth() - 1) / 7) + 1;
}
... but you could do the same using Calendar and fetching the value of the Calendar.DAY_OF_MONTH field.
EDIT: Actually, I've just noticed that for a change, java.util.Calendar is actually simpler than Joda Time - there's a particular field for it! All you need is:
int weekOfWeekDay = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
From the docs for DAY_OF_WEEK_IN_MONTH:
Field number for get and set indicating the ordinal number of the day of the week within the current month. Together with the DAY_OF_WEEK field, this uniquely specifies a day within a month. Unlike WEEK_OF_MONTH and WEEK_OF_YEAR, this field's value does not depend on getFirstDayOfWeek() or getMinimalDaysInFirstWeek(). DAY_OF_MONTH 1 through 7 always correspond to DAY_OF_WEEK_IN_MONTH 1; 8 through 14 correspond to DAY_OF_WEEK_IN_MONTH 2, and so on.
I think I'd probably still use the Joda Time version because it's just a much nicer API all round, but if you're forced to use Calendar, at least you can do this in one shot.

Working with Date and Calendar

I have a datepicker where the user selects a date and then a checkbox on what type of period he wants to get the date from. For example:
User selects the 1. of November and selects the checkbox "Month" in this case the end date will be increased by 1 and even if this sound simple enough its slowly starting to annoy me alot!
The problem is that Java doesnt have a great date object that works for this kind of thing so i thought that i would use Calendar but it isnt easy to increment a calendar date take for instance the following example:
endDate.set(startDate.YEAR, startDate.MONTH+1, startDate.DATE);
in theory this would increment the month by one being one larger than the start date. This works in about 90 % of the months EXECPT from December if you increase the month by 1 in December then the integer month return 13 same thing happens for startDate.DATE; and startDate.Year;
My question is isnt there an easier way to do this? i could make a ton of If sentences but i really think that it is kinda redundant.
Use add method of java.util.Calendar.
endDate.set(startDate.YEAR, startDate.MONTH, startDate.DATE);
if(some_condition) {
endDate.add(Calendar.MONTH, 1);
}
You can use Calendar.add() to add values to the calendar value, e.g. Calendar.add(Calendar.MONTH, 1) this adds one month and takes into account that January is after December.
The standard recomendation here is to look at Joda-Time (see here for more info). It's a much more consistent/capable API with none of the threading issues that plague the standard Java date/formatting APIs and as such is widely used and accepted.
In terms of what you want above, I would suggest something like:
LocalDate d = ...
LocalDate nd = d.plusMonths(1);
The above will correctly handle month/year rollovers.

How to find which day of the week it is java

I want to find the day of the week in java without the use of date and other methods that do it on theirselves.I can find the daydifference between 2 dates but I cant understand how I can find which day of the week that specific date is.
If you can find the day difference between two days, then just use the mod operator.
For instance, if you know that day1 = Monday, and you want to find which day it is after 701 days, it is Monday + 701 % 7 = Monday + 1 = Tuesday.
There are formulas for figuring out what day of the week a particular day is on:
http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Purely_mathematical_methods
The approach you've chosen seems extremely complicated and error prone.
I suggest creating your own class named Date.
A date will contain a month, day, and year and will know how to subtract or add days.
It should also be able to determine if it is equal to, before, or after another date.
You should use an array of ints to represent the number of days in each month.
This array can be a private static field of your Date class.
Then you can create an instance of your class that represents date2 and subtract one day at a time until it equals date1.
You can use a similar approach to determine the day of the week by comparing the input dates to a base date with a known day of week.
I'm certain this is what your instructor intended for this assignment.
This will teach you a valuable lesson:
Take advantage of objects to use encapsulation in stead of using a bunch of if statements.

Categories

Resources