Sorry for asking daft question but I cannot get correct number of weeks in June 2014 returned by Calendar:
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, Calendar.JUNE);
calendar.set(Calendar.YEAR, 2014);
calendar.setFirstDayOfWeek(Calendar.MONDAY);
System.out
.println("first day of week: " + calendar.getFirstDayOfWeek());
System.out.println("weeks in month: "
+ calendar.getActualMaximum(Calendar.WEEK_OF_MONTH));
System.out.println("days in month: "
+ calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
}
I am getting:
first day of week: 2
weeks in month: 5
days in month: 30
Why number of weeks in June 2014 is not 6? I am using jdk1.8.0_05 on Mac OS X 10.9.3.
The definition of a week depends on what each Locale (country, region, whatever) defines as the first day of the week. You can check that with Calendar#getFirstDayOfWeek(). It also depends on what it considers the minimal days in the first week should be. You can get that with Calendar#getMinimalDaysInFirstWeek(). Your Locale seems to show that it needs more than one day to consider that period a week.
For example, with Locale.CANADA, I get 6 weeks since the getMinimalDaysInFirstWeek() returns 1.
Related
This question already has answers here:
Y returns 2012 while y returns 2011 in SimpleDateFormat
(5 answers)
Why does sdf.format(date) converts 2018-12-30 to 2019-12-30 in java? [duplicate]
(3 answers)
Closed 3 years ago.
From document SimpleDateTimePattern, yy should be the same with YY.
Today is Dec 30, 2019, now we get YY for today is 20, yy for today is 19. What's the difference between yy and YY in Java Time Pattern?
yy is the calendar year, while YY is a week year. A week year can be different from the calendar year depending on which day the first of January falls. For example see ISO-8601 week year.
Today (30 December 2019) is a good example, the calendar year is 2019, but the week year is 2020, because this week is week 1 of 2020. So yy will result in 19, while YY results in 20.
The definition of the first week of a year from the wikipedia page:
The ISO 8601 definition for week 01 is the week with the Gregorian
year's first Thursday in it. The following definitions based on
properties of this week are mutually equivalent, since the ISO week
starts with Monday:
It is the first week with a majority (4 or more) of its days in January.
Its first day is the Monday nearest to 1 January.
It has 4 January in it. Hence the earliest possible first week extends from Monday 29 December (previous Gregorian year) to Sunday 4
January, the latest possible first week extends from Monday 4 January
to Sunday 10 January.
It has the year's first working day in it, if Saturdays, Sundays and 1 January are not working days.
If 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in
week 01. If 1 January is on a Friday, it is part of week 53 of the
previous year. If it is on a Saturday, it is part of the last week of
the previous year which is numbered 52 in a common year and 53 in a
leap year. If it is on a Sunday, it is part of week 52 of the previous
year.
Some locales, like for example the US, don't follow ISO-8601, because there they use Sunday as the first day of the week, but they have similar rules for week years.
You have it in you link:
y Year Year 1996; 96
Y Week year Year 2009; 09
Week year can be different, for example this new year week, than current year
Week year defines as year's first Thursday:
The first week of the year is the week that contains that year's first Thursday
They both represent a year but yyyy represents the calendar year while
YYYY represents the year of the week.
An example illustrates this much better than words ever could.
package datetest;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) {
try {
String[] dates = {"2018-12-01", "2018-12-31", "2019-01-01"};
for (String date: dates) {
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
Date d = dt.parse(date);
SimpleDateFormat dtYYYY = new SimpleDateFormat("YYYY");
SimpleDateFormat dtyyyy = new SimpleDateFormat("yyyy");
System.out.println("For date :" + date + " the YYYY year is : " + dtYYYY.format(d) + " while for yyyy it's " + dtyyyy.format(d));
}
} catch (Exception e) {
System.out.println("Failed with exception: " + e);
}
}
}
Output
For date : 2018-12-01 the YYYY year is : 2018 while for yyyy it's 2018
For date : 2018-12-31 the YYYY year is : 2019 while for yyyy it's 2018
For date : 2019-01-01 the YYYY year is : 2019 while for yyyy it's 2019
This is a question related to Java Date year calculation is off by year for two days
I understand the problem appeared from using 'YYYY' instead of 'yyyy', whereby 'YYYY' refers to calendar year instead of the actual year, resulting in the year being wrong if the dates fell onto the first week of January's calendar year.
I tried to read further and understand the problem in
https://docs.oracle.com/javase/9/docs/api/java/util/GregorianCalendar.html#week_year
And it says
"A week year is in sync with a WEEK_OF_YEAR cycle. All weeks between the first and last weeks (inclusive) have the same week year value. Therefore, the first and last days of a week year may have different calendar year values."
I have been trying to see if there are any time of the year where 01-Jan-XXXX is actually displayed as 01-Jan-(XXXX-1) but have not managed to find any. Is there a case where this may happen?
I did something simple to take string dates and print out using YYYYMMdd format
public static void main(String[] args) throws ParseException
{
Calendar testCalendar = Calendar.getInstance();
System.out.println("First day of the week: " + testCalendar.getFirstDayOfWeek());
System.out.println("Minimal Days in First Week: " + testCalendar.getMinimalDaysInFirstWeek());
SimpleDateFormat YYYYMMdd= new SimpleDateFormat("YYYYMMdd");
String dateString = "01/01/2016";
Date date = new Date();
date = new SimpleDateFormat("dd/MM/yyyy").parse(dateString);
testCalendar.setTime(date);
int week = testCalendar.get(Calendar.WEEK_OF_YEAR);
String date2 = YYYYMMdd.format(date);
System.out.println("Week Number: " + week);
System.out.println("Date: " + date2);
}
And the output was
First day of the week: 1
Minimal Days in First Week: 1
Week Number: 1
Date: 20161231
If I change the date to "01/01/2016"
The output was
First day of the week: 1
Minimal Days in First Week: 1
Week Number: 1
Date: 20160101
So 01/01/2016 is the first week of of 2016, and not week 53 of 2015.
For a concrete answer, the following table shows January 1 for each year from 2010 through 2020 with day-of-week, week-based year and week number in ISO (the international standard) and in the US.
Year DOW ISO US
2010 Fri 2009-53 2010-01
2011 Sat 2010-52 2011-01
2012 Sun 2011-52 2012-01
2013 Tue 2013-01 2013-01
2014 Wed 2014-01 2014-01
2015 Thu 2015-01 2015-01
2016 Fri 2015-53 2016-01
2017 Sun 2016-52 2017-01
2018 Mon 2018-01 2018-01
2019 Tue 2019-01 2019-01
2020 Wed 2020-01 2020-01
As you can see, internationally January 1 regularly falls in week 52 or 53 of the previous year, while in the US it always falls in week 1 of its own year.
International rule: Week 1 is the first one that contains at least 4 days of the new year. In other words, a week belongs in the year where most of its days are. In yet other words, week 1 is the one that holds the first Thursday of the year (since weeks begin on Mondays). This implies that when January 1 is a Friday, Saturday or Sunday, it belongs to the last week of the previous year.
US rule: Week 1 is the week that contains January 1. That January 1 always falls in week 1 of its own year follows from this definition (weeks begin on Sundays).
The table came out of this snippet:
System.out.println("Year DOW ISO US");
for (int year = 2010; year <= 2020; year++) {
LocalDate jan1 = LocalDate.of(year, Month.JANUARY , 1);
System.out.format(Locale.ROOT, "%4d %3s %4d-%02d %4d-%02d%n",
year, jan1.getDayOfWeek().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ROOT),
jan1.get(WeekFields.ISO.weekBasedYear()), jan1.get(WeekFields.ISO.weekOfWeekBasedYear()),
jan1.get(WeekFields.SUNDAY_START.weekBasedYear()), jan1.get(WeekFields.SUNDAY_START.weekOfWeekBasedYear()));
}
I am of course using java.time, the modern Java date and time API. I warmly recommend it over the outdated Calendar, SimpleDateFormat and Date.
No. The week year is only to be used in conjunction with the week. For example the 1st January 2016 (a Friday) is in the 53. week of 2015. It will never be displayed as 1. January 2015 since that would be ambiguous.
Calendar d = Calendar.getInstance();
d.set(Calendar.YEAR, 2016)
d.set(Calendar.MONTH, Calendar.JANUARY);
d.set(Calendar.DATE, 1);
SimpleDateFormat ft = new SimpleDateFormat("w-YYYY");
ft.format(d.getTime());
// => "53-2015"
In the US, the first week of the year is defined as being the week containing January 1*.
As a consequence, the week-year for January 1 will always be the same as the calendar year, in the US.
*https://en.wikipedia.org/wiki/Week#Week_numbering
This question already has answers here:
Get last week date range for a date in Java
(5 answers)
Closed 5 years ago.
My requirement is to get the start and end date of the week when date is passed. I have searched and i found tons of answers but confused with which one is best to use.In one of the thread i found the below code:
Calendar c = Calendar.getInstance();
c.setTime(new Date("8/16/2017"));
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
System.out.println("day :" + dayOfWeek);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
System.out.println("start of week day :" + c.getTime());
output:
day :4
start of week day :Sun Aug 13 00:00:00 EDT 2017
I see a bug in the above code output. Start of the week should be Monday Aug14 but it shows Sun Aug13. Any suggestions to get the start date and end date of the week when date is passed as a String dynamically.
--EDITED--
I'm looking for java code which returns the first and last day date's of the week when date is passed.
import java.time.LocalDate;
import static java.time.DayOfWeek.MONDAY;
import static java.time.DayOfWeek.SUNDAY;
import static java.time.temporal.TemporalAdjusters.nextOrSame;
import static java.time.temporal.TemporalAdjusters.previousOrSame;
public class FirstAndLast
{
public static void main(String[] args)
{
LocalDate today = LocalDate.now();
LocalDate monday = today.with(previousOrSame(MONDAY));
LocalDate sunday = today.with(nextOrSame(SUNDAY));
System.out.println("Today: " + today);
System.out.println("Monday of the Week: " + monday);
System.out.println("Sunday of the Week: " + sunday);
}
}
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY); //Line2
c.setTime(new Date("8/16/2017"));
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
System.out.println("day :" + dayOfWeek);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
System.out.println("start of week day :" + c.getTime());
Set the first day of the week to Monday as in line 2.
Now the output will be
day :4
start of week day :Mon Aug 14 00:00:00 EDT 2017
The Unix timestamp is 1417029117, which is 11/26/2014, Wednesday.
long timestamp = 1417029117l*1000l;
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timestamp);
System.out.println("current day is "+cal.get(Calendar.DAY_OF_WEEK));
System.out.println("current month is "+cal.get(Calendar.MONTH));
And I got the results as follows:
current day is 4
current month is 10
Any explanation? If January is 0 then the month is fine. But why the day is 4?
First day of the week is Sunday. So, Wednesday is 4. See Calendar#DAY_OF_WEEK and Constant Field Values, Calendar#WEDNESDAY, it's plain out there in the documentation.
I like to know which week of the month a particular day falls. For example 20-Sep-2012 falls on 4th week of September but the below code displays it as 3 which is not correct. The system is dividing the days by 7 and returning the output and which is not I require. I have searched in Joda API's but not able to find the solution. Please let me know is there any way to figure out the week of a month, a day falls
Calendar ca1 = Calendar.getInstance();
ca1.set(2012,9,20);
int wk=ca1.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month :"+wk);
This is due to two reasons:
The first one is this (from the API):
The first week of a month or year is defined as the earliest seven day period beginning on getFirstDayOfWeek() and containing at least
getMinimalDaysInFirstWeek() days
The default value for this varies (mine was 4), but you can set this to your preferred value with
Calendar.setMinimalDaysInFirstWeek()
The second reason is the one #Timmy brought up in his answer. You need to perform both changes for your code to work. Complete working example:
public static void main(String[] args) {
Calendar ca1 = Calendar.getInstance();
ca1.set(2012, Calendar.SEPTEMBER, 20);
ca1.setMinimalDaysInFirstWeek(1);
int wk = ca1.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month :" + wk);
}
This prints
Week of Month :4
Month is zero-based. So ca1.set(2012,9,20) is actually setting the calendar to October.
To get sure the right month is set try using the month-constants provided by the Calendar-Class.
For those working with Joda time, this is what I am using:
/**
* For a week starting from Sunday, get the week of the month assuming a
* valid week is any week containing at least one day.
*
* 0=Last,1=First,2=Second...5=Fifth
*/
private int getWeekOfMonth( MutableDateTime calendar )
{
long time = calendar.getMillis();
int dayOfMonth = calendar.getDayOfMonth();
int firstWeekday;
int lastDateOfMonth;
int week;
int weeksInMonth;
calendar.setDayOfMonth( 1 );
firstWeekday = calendar.getDayOfWeek();
if (firstWeekday == 7)
{
firstWeekday = 0;
}
calendar.setHourOfDay( 0 );
calendar.addMonths( 1 );
calendar.addDays( -1 );
lastDateOfMonth = calendar.getDayOfMonth();
weeksInMonth = (int)Math.ceil( 1.0*(lastDateOfMonth + firstWeekday)/7 );
week = (byte)(1 + (dayOfMonth + firstWeekday - 1)/7);
week = (week == weeksInMonth)?0:week;
calendar.setMillis( time );
return week;
}
I'm very late to this question, but I feel the full answer is missing, which is, that how weeks are interpreted can differ quite a lot depending on the Locale.
The question seems to need the settings for the US (or a similar Locale), which uses 1 as minimal days in first week, and Sunday as the first day of the week.
The question, and all the answers take a default Calendar instance which comes with 4 as minimal days in first week, and Monday as first day of the week.
A simple demo program shows this :
public static void main(String[] args) {
{
System.out.println("--- ISO ---");
Calendar calendar = Calendar.getInstance();
System.out.println("First day of week : " + calendar.getFirstDayOfWeek());
System.out.println("Minimal days in 1st week : " + calendar.getMinimalDaysInFirstWeek());
calendar.set(2012, Calendar.SEPTEMBER, 20);
int wk = calendar.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month : " + wk);
}
{
System.out.println("--- USA ---");
Calendar calendar = Calendar.getInstance(Locale.US);
System.out.println("First day of week : " + calendar.getFirstDayOfWeek());
System.out.println("Minimal days in 1st week : " + calendar.getMinimalDaysInFirstWeek());
calendar.set(2012, Calendar.SEPTEMBER, 20);
int wk = calendar.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of Month : " + wk);
}
}
And that yields this output :
--- ISO ---
First day of week : 2
Minimal days in 1st week : 4
Week of Month : 3
--- USA ---
First day of week : 1
Minimal days in 1st week : 1
Week of Month : 4
CONCLUSION :
There's no need to manually set the minimal days in first week, or the first day of week. Just make sure you're using the right Locale.
Extra
Joda time only had support for ISO weeks.
Since Java 8 and the new time API you can go about it like this :
LocalDate localDate = LocalDate.of(2012, 9, 20);
TemporalField usWeekOfMonth = WeekFields.of(Locale.US).weekOfMonth();
TemporalField isoWeekOfMonth = WeekFields.ISO.weekOfMonth();
System.out.println("USA week of month " + usWeekOfMonth.getFrom(localDate));
System.out.println("ISO week of month " + usWeekOfMonth.getFrom(localDate));
Output :
USA week of month 4
ISO week of month 4
And there's even support in the formatter :
DateTimeFormatter usDateTimeFormatter = DateTimeFormatter.ofPattern("W/MM")
.withLocale(Locale.US);
System.out.println("USA formatter : " + usDateTimeFormatter.format(localDate));
DateTimeFormatter isoDateTimeFormatter = DateTimeFormatter.ofPattern("W/MM");
System.out.println("ISO formatter : " + isoDateTimeFormatter.format(localDate));
Output :
USA formatter : 4/09
ISO formatter : 3/09
class test {
public static void main(String[] args){
Calendar cal = Calendar.getInstance();
cal.set(2016, Calendar.AUGUST, 01);
printDayOFWeek(cal, Calendar.MONDAY, 5);//prints monday on 5th week
}
}
private static void printDayOFWeek(Calendar cal, int day, int whatweek) {
cal.set(Calendar.DAY_OF_WEEK, day);//day = Mon, tue, wed,..etc
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1); //-1 return last week
Date last = cal.getTime();
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, whatweek);
Date one = cal.getTime();
if(one.before(last) || one.compareTo(last) ==0)
{
System.out.println(whatweek +"WEEK" + cal.getTime());
}
}