I have this object Date in this format : 2014-05-20 18:17:26.337
I try to do this:
Calendar c = Calendar.getInstance();
c.setTime(myDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);
int Month = c.get(Calendar.MONTH);
int year = c.get(Calendar.YEAR);
But the information are wrong..
How I can resolve it?
This is the expected value, please read the javadoc carefully:
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#MONTH
For Month:
Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
For day of week:
public static final int DAY_OF_WEEK
Field number for get and set indicating the day of the week. This field takes values SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY.
From java doc:
Blockquote
int java.util.Calendar.MONTH = 2 [0x2]
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
See Also: JANUARY FEBRUARY MARCH APRIL MAY JUNE JULY AUGUST SEPTEMBER
OCTOBER NOVEMBER DECEMBER UNDECIMBER
You need to read Java doc first
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
So you will get month as 4
int month = c.get(Calendar.MONTH);
Related
If you consider that week will start from Jan 01 of every year & week start is SUNDAY then there will be 53 weeks in 2019.
Following above Jan 29,30,31 2019 will be into Week-53 of 2019.
As given in documentation of IsoFields for WEEK_OF_WEEK_BASED_YEAR that all three fields are validated against their range of valid values. The week-of-week-based-year field is validated from 1 to 52 or 53 depending on the week-based-year.
So I'm assuming that following code should give the output as: WEEK_OF_WEEK_BASED_YEAR 53 & WEEK_BASED_YEAR 2019.
But it's giving output as: 1 & 2020
import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.IsoFields;
public class WeekStartDemo {
public static void main(String args[]) {
DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
.ofPattern("uuuu-MM-dd")
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
LocalDate updatedDate = LocalDate.parse("2019-12-30", DATE_FORMATTER);
System.out.println(updatedDate.toString());
System.out.println(updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(updatedDate.get(IsoFields.WEEK_BASED_YEAR));
}
}
If I pass the date as 2019-12-28 then it's returning WEEK_OF_WEEK_BASED_YEAR 52 & WEEK_BASED_YEAR 2019. But doesn't work for last week of 2019 (which is 53rd week)
Let me know what I'm missing in above code.
As I mentioned in the comments, and from your Javadoc link for IsoFields, The week-based-year itself is defined relative to the standard ISO proleptic year. It differs from the standard year in that it always starts on a Monday (not a Sunday). It should be easy enough to find the years with 53 weeks using your posted code, iterate from 1900 to 2300 and parse the WEEK_OF_WEEK_BASED_YEAR for the last day of the given year and print the values where it is 53. Like,
DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd")
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
for (int i = 1900; i < 2300; i++) {
LocalDate updatedDate = LocalDate.parse(String.format("%d-12-31", i), DATE_FORMATTER);
if (updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) == 53) {
System.out.println(i);
}
}
The first few values I get are
1903
1908
1914
1920
1925
1931
1936
1942
skipping ahead a bit...
2009
2015
2020
2026
So this year (2020) has 53 weeks, and 2019 does not.
LocalDate date = LocalDate.of(2019, Month.DECEMBER, 30);
int weekOfYear = date.get(WeekFields.SUNDAY_START.weekOfYear());
System.out.println(weekOfYear);
Output from this snippet is:
53
I believe that this is the exact difference between WeekFields.weekOfWeekBasedYear() and WeekFields.weekOfYear().
It may also be that your main source of confusion is using the wrong week fields, as Elliott Frisch also mentioned. The ISO week fields that you use define Monday as the first day of the week and week one of the year as the first week containing at least 4 days of the year. In contrast you said that you wanted:
If you consider that week will start from Jan 01 of every year &
week start is SUNDAY …
From your comments:
… will the new week (Week-01) will always start on Jan 01 of every year ?
Yes it will.
How can I perform minus 1 week on this weekOfYear ? As for Jan
01,2020, weekOfYear will be Week-01 2020. What type of minus 1
week I can perform to get weekOfYear as Week-53 2019 ? I tried
with date.minusWeeks(1) but it returns Week-52 2019
LocalDate dateInWeek1 = LocalDate.of(2020, Month.JANUARY, 3);
int weekOfYear = dateInWeek1.get(wf.weekOfYear());
System.out.println(weekOfYear);
LocalDate dateInPreviousWeek;
if (weekOfYear == 1) {
dateInPreviousWeek = dateInWeek1.minusWeeks(1)
.with(TemporalAdjusters.lastDayOfMonth());
}
else {
dateInPreviousWeek = dateInWeek1.minusWeeks(1);
}
System.out.format("%s %2d%n", dateInPreviousWeek, dateInPreviousWeek.get(wf.weekOfYear()));
We need to handle the case of week 1 specially. When subtracting 1 week, we know we are getting into December the previous year. Selecting the last day of the month will give us December 31. This will always be in the last week of the year (usually week 53; occasionally week 54 if in a leap year that begins on a Saturday, I think that years 2000 and 2028 are examples of this).
The issue here is that a given year has either 365 or 366 days (the latter for a leap year), which means that every year has either 1 or 2 days extra beyond 52 weeks. The ISO system for week years is what handles this, and it means that sometimes the first week of the year might not start of the 1st of January, nor would the last day of a year fall in the 52nd week. One workaround here would be to just calculate the week starting from the beginning of each year, e.g.
LocalDate firstOfYear = LocalDate.of(2019, Month.JANUARY, 1);
LocalDate updatedDate = LocalDate.of(2019, Month.DECEMBER, 30);
int diff = (int)ChronoUnit.DAYS.between(firstOfYear, updatedDate);
int week = 1 + (diff / 7);
System.out.println("The week number is: " + week);
Based on the ISO-8601 (https://www.cl.cam.ac.uk/~mgk25/iso-time.html) this is correct. 2019 has no calendarweek 53. Week 01 of a year is per definition the first week that has the Thursday in this year, which is equivalent to the week that contains the fourth day of January.
As far as I know this is done to avoid a cw 1 without a workday.
I need to find which nth dayOfWeek a particular day is in the month for a date in Java. For example, today is April 20th, 2016 which is the 3rd Wednesday in the month or October 31, 2016 which is the 5th Monday in October. How can I find which number the particular occurrence of a day is in the month?
Use the get method of the Calendar class.
public static int getOccurenceOfDayInMonth() {
return Calendar.getInstance().get(Calendar.DAY_OF_WEEK_IN_MONTH);
}
[EDIT]
Here is a solution given any date, rather than the current date.
public static int getOccurenceOfDayInMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
}
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, Calendar.OCTOBER);
c.set(Calendar.DAY_OF_MONTH, 31);
c.set(Calendar.MONTH, c.get(Calendar.MONTH)+1); //Returns Dec 1. Expect Nov 30.
If I have a calendar object and the last day of a month falls on the 31st and the next month has less days than the previous, how can I ensure that by setting the month ahead I will not go beyond the next month?
Use add() instead of set() as the Calendar is "smart" enough to determine the difference of days and such...
public static void main(String[] args) throws Exception {
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, Calendar.OCTOBER);
c.set(Calendar.DAY_OF_MONTH, 31);
c.add(Calendar.MONTH, 1);
System.out.println(c.getTime());
}
Output (as of my current run):
Sun Nov 30 09:08:01 EST 2014
According to the Calendar JavaDocs:
Leniency
Calendar has two modes for interpreting the calendar fields, lenient
and non-lenient. When a Calendar is in lenient mode, it accepts a
wider range of calendar field values than it produces. When a Calendar
recomputes calendar field values for return by get(), all of the
calendar fields are normalized. For example, a lenient
GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as
February 1.
This means that when you add 1 to the MONTH, the value of DAY_OF_MONTH is still 31. But November doesn't have a 31st day. This means that if the Calendar you are using is lenient, it will interpret MONTH == 11, DAY_OF_MONTH == 31 as December 1.
Date fakeDate = sdf.parse("15/07/2013 11:00 AM");
Calendar calendar = Calendar.getInstance()
calendar.setTime(fakeDate);
int currentMonth = calendar.get(Calendar.MONTH);
I get currentMonth == 6 instead of 7.
why is that?
Because Calendar.MONTH is ZERO based. Why?
Check the docs: (always)
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
As the doc says - Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
So try something like this
int currentMonth = calendar.get(Calendar.MONTH)+1;
Because
calendar.get(Calendar.MONTH) shall give you (currentMonthValue-1) as the value of january starts with 0
It should be
int currentMonth = calendar.get(Calendar.MONTH)+1;
From http://www.coderanch.com/t/381676/java/java/number-months-between-two-given, one post mentioned:
public static int monthsBetween(Date minuend, Date subtrahend)
{
Calendar cal = Calendar.getInstance();
// default will be Gregorian in US Locales
cal.setTime(minuend);
int minuendMonth = cal.get(Calendar.MONTH);
int minuendYear = cal.get(Calendar.YEAR);
cal.setTime(subtrahend);
int subtrahendMonth = cal.get(Calendar.MONTH);
int subtrahendYear = cal.get(Calendar.YEAR);
// the following will work okay for Gregorian but will not
// work correctly in a Calendar where the number of months
// in a year is not constant
return ((minuendYear - subtrahendYear) * cal.getMaximum(Calendar.MONTH)) +
(minuendMonth - subtrahendMonth);
}
Is it true that the number of months in a Calendar is not constant? And why?
Yes. In the hebrew calendar, there are several years with 13 months (7 out of 19 to be exact).
It is funny that, month comes from moon. A lunar calendar usually sync days with moon phases, so that, for example, day 15 of any month is always a full moon day.
The problem is a solar year is not exactly 12 moon cycles. So a lunar calendar must have "leap months".