Get Date of Specific Week - java

I'm trying to get the start and end date of specific week of a month. However the date is incorrect. Can anyone identify what's the issue ?
public class DateUtils
{
getWeeklyDateList(2020,5, 3);
public static void getWeeklyDateList(int year, int month, int week)
{
Calendar calendar = Calendar.getInstance(Locale.getDefault());
// setting year, month, week
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.WEEK_OF_MONTH,week);
// setting day of week to first --> Sunday
calendar.set(Calendar.DAY_OF_WEEK, 1);
int year1 = calendar.get(Calendar.YEAR);
int month1 = calendar.get(Calendar.MONTH);
int day1 = calendar.get(Calendar.DAY_OF_MONTH);
// setting day of week to last --> Saturday
calendar.set(Calendar.DAY_OF_WEEK, 7);
int year7 = calendar.get(Calendar.YEAR);
int month7 = calendar.get(Calendar.MONTH);
int day7 = calendar.get(Calendar.DAY_OF_MONTH);
Log.e("date_start", String.valueOf(year1) + "-" + String.valueOf(month1) + "-" + String.valueOf(day1));
Log.e("date_end", String.valueOf(year7) + "-" + String.valueOf(month7) + "-" + String.valueOf(day7));
} }

java.time and ThreeTenABP
If you want to use java.time, the modern Java date and time API, it can be done with this simple method:
private static WeekFields wf = WeekFields.of(Locale.forLanguageTag("ne-NP"));
public static void getWeeklyDateList(int year, Month month, int week) {
LocalDate someDateInTheWeek = LocalDate.of(year, month, 10).with(wf.weekOfMonth(), week);
LocalDate start = someDateInTheWeek.with(wf.dayOfWeek(), 1);
LocalDate end = someDateInTheWeek.with(wf.dayOfWeek(), 7);
System.out.println("date_start: " + start);
System.out.println("date_end: " + end);
}
Trying it out with your example arguments:
getWeeklyDateList(2020, Month.JUNE, 3);
Output is:
date_start: 2020-06-14
date_end: 2020-06-20
How it works:
First, weeks are defined differently in different cultures. In Nepal (since you give Kathmandu, Nepal as your location) weeks start on Sunday and are numbered in a way where the 1st of the month is in week 1 of the month. To handle this week scheme I am initializing a WeekFields object for Nepalese culture.
LocalDate is the java.time class for a date without time of day. I don’t think it matters which day of the month I pick as a starting point; I took the 10th. From that date I get a date in the correct week, using the WeekFields object and the supplied week number. From there in turn I get the first and the last day of the week, again according to the Nepalese definition of weeks: from Sunday June 14 through Saturday June 20 2020.
What went wrong in your code I cannot tell. In any case the Calendar class you used is poorly designed and long outdated. It also default uses the default locale of the JVM for its week definition, which may have given you a different week scheme from what you wanted. A final point that may have confused you: Calendar unnaturally numbers months from 0 for January through 11 for December. So when you specified 5, you got June (not May). You printed out the month numbers of your result dates, which probably again printed 5 (not 6) for June.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Question: Why is January month 0 in Java Calendar?

Its because of this line,
calendar.set(Calendar.DAY_OF_WEEK, 1);
this can take month to previous month if week starts in previous one. If there is a month difference then this is the problem.

Related

Convert month and day number to day of year using CALENDAR

I have two numbers.
First would be the month number.
Second would be the day number.
I also know the year.
How can I take those two number, month and day and make it into a single number DAY_OF_YEAR?
I'm using Java 1.7 and the Calendar functions.
java.time through ThreeTen Backport
int year = 2019;
int monthNumber = 9;
int dayNumber = 28;
LocalDate date = LocalDate.of(year, monthNumber, dayNumber);
int dayOfYear = date.getDayOfYear();
System.out.println("Day of year is " + dayOfYear);
Output from this snippet is:
Day of year is 271
Tested on Java 1.7.0_79 using ThreeTen Backport 1.3.6 and importing org.threeten.bp.LocalDate.
Consider avoiding the Calendar class
Four lines of the currently accepted answer creating and setting the Calendar object are substituted by just one line here. It’s typical for code using Calendar to be so wordy, which we shouldn’t want. Also despite the name a Calendar object is more than a calendar date, it also carries with it a time of day, a time zone and more, so I do not consider it a good fit for the job at hand. The code using Calendar will give a different result if the default locale is Thai, which will surprise most. The Calendar class is poorly designed and long outdated.
Instead I am using LocalDate of java.time, the modern Java date and time API.
Question: Can I use java.time on Java 7?
I'm using Java 1.7 …
java.time works nicely on Java 7. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Just using calendar and assuming by number of month you mean the zero-indexed one where 0 means January, here is an example for May 13th 2019:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
c.set(Calendar.YEAR, 2019);
c.set(Calendar.MONTH, 4);
c.set(Calendar.DAY_OF_MONTH, 13);
System.out.println(c.get(Calendar.DAY_OF_YEAR));
Edit: As Ole V.V.'s answer pointed out you get a Calendar object with the system's timezone if you call 'Calendar.getInstance()', so I changed it that way that you explicitly specify the timezone and Locale to be used. The latter is important if you e.g. want to get a date's week number where the rules differ in different regions of the world.
You can concat your parts into a String, and use a SimpleDateFormatter like:
int year = 2019;
int month = 1;
int day = 23;
String string = "" + year + "-" + month + "-" + day;
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(string);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
The example is for 2019 January 23.

Is it possible to get time difference from directly Calendar fields?

sorry if the title is confusing. Let me explain clearly. I need to play with days, months and years. In order to do this I use Calendar. Here is my code;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int dayStart=0,monthStart=0,yearStart=0,dayFinish=0,monthFinish=0,yearFinish=0;
Calendar cal = (Calendar) Calendar.getInstance();
cal.set(Calendar.MONTH,Calendar.MAY); //SET MONTH AS MAY
cal.set(Calendar.DATE,1);
cal.set(Calendar.YEAR,2018);
monthStart=(cal.getCalendar.MONTH)+1);
dayStart=cal.get(Calendar.DATE);
yearStart=cal.get(Calendar.YEAR);
System.out.println("STARTING DAY: "+dayStart+" STARTING MONTH: "+monthStart+" STARTING YEAR: "+yearStart);
cal.add(Calendar.MONTH,6); //ADD 6 MONTHS
monthFinish = (cal.get(Calendar.MONTH)+1);
dayFinish = (cal.get(Calendar.DATE));
yearFinish = (cal.get(Calendar.YEAR));
System.out.println("FINISHING DAY: "+dayFinish+" FINISHNG MONTH: "+monthFinish+" FINISHING YEAR: "+yearFinish);
//WHAT I WANT IS printing out the days between 2 dates: 184
}
First, I set the time: 1 5 2018, then I add 6 months and the time becomes 1 11 2018. I need to get day difference as 184 (If I set the month January, it should be 181) Is it possible to do it just converting the corresponding Calendar fields (date,month,year) to secs or milliseconds and subtract millisecond value of (1 5 2018) from the (1 11 2018) and convert back milliseconds to days? There are similar questions but I couldn't find the solution exactly in the way I want.
java.time
LocalDate start = LocalDate.of(2018, Month.MAY, 1);
LocalDate finish = start.plusMonths(6);
long daysBetween = ChronoUnit.DAYS.between(start, finish);
System.out.format("Days between %s and %s: %d%n", start, finish, daysBetween);
IMHO it’s clear and it’s brief. And the bonus, it works correctly. Output is:
Days between 2018-05-01 and 2018-11-01: 184
The Calendar class has design problems and is now long outdated. So I recommend using java.time, the modern Java date and time API, instead. There is a way to have a Calendar count days correctly, but it’s more complicated than you would expect, and there is no reason why you should want to bother. Calculating the days from the milliseconds (which is shown in several answers on Stack Overflow, not only the other answer to this question) will sometime give the correct result, sometimes not. The two issues are: (1) Due to summer time (DST) and other discontinuities a day may be 23, 24 or 25 hours or some number between or even outside this interval. If a day in the interval is shorter than 24 hours, converting from the milliseconds will yield 1 day too little. (2) A Calendar (despite its name) also holds time of day. In your code it will hold the same time of day before and after you add 6 months. In other cases the different time of day may cause you to get 1 day too few, or in rare cases 1 day too many.
Question: Can I use java.time on Android?
Yes, java.time works nicely on Android devices. It just requires at least Java 6.
In Java 8 and later and on new Android devices (from API level 26, I’m told) the new API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310, where the modern API was first described).
On (older) Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. Make sure you import the date and time classes from package org.threeten.bp and subpackages.
Links
Oracle tutorial: Date Time, explaining how to use java.time.
ThreeTen Backport project
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Java Specification Request (JSR) 310.
You can try the something similar to this should work for you
import java.util.*;
import java.util.concurrent.TimeUnit;
public class Calendar1 {
public static void main(String args[])
{
Calendar startDate = Calendar.getInstance();
//Setting year, month and day
startDate.set(2018, 5, 1);
Calendar endDate = Calendar.getInstance();
endDate.set(2018, 11, 1);
long end = endDate.getTimeInMillis();
long start = startDate.getTimeInMillis();
System.out.println("Time difference in days " + TimeUnit.MILLISECONDS.toDays(Math.abs(end - start)));
}
}
Something this you can do. Change the year, Month and Date and set in the calendar.
Use java.time.temporal.ChronoUnit to get the difference.
The sample code is as below.
public void daysBetween() {
Calendar startOfMonth = Calendar.getInstance();
startOfMonth.set(Calendar.YEAR, 2018);
startOfMonth.set(Calendar.MONTH, 10);
startOfMonth.set(Calendar.DAY_OF_MONTH, 1);
Calendar endOfMonth = Calendar.getInstance();
endOfMonth.set(Calendar.YEAR, 2018);
endOfMonth.set(Calendar.MONTH, 10);
endOfMonth.set(Calendar.DAY_OF_MONTH, 30);
System.out.println(ChronoUnit.DAYS.between(startOfMonth.toInstant(),endOfMonth.toInstant()));
}

check if a date is equal independently of the year

I use javaSE 1.6 and I need to compare two dates and check if they are the same. this check needs to be independent of the year.
for example, i need to identify if today is the B-day of someone, and I need this code to be reused in the coming years.
so I need to perform the check, not on the year, not even on the day-of-the-year (issue with Leap year) but I can only rely on the day-of-the-month and the month number itself.
my input data, the birthday day of the person, it is in the Java class "Date"
is there any method of javaSE 1.6 that could help me?
I checked classes "Date" and "Calendar", but so far I couldn't find any hint to solve my issue.
ThreeTen Backport
public static MonthDay toMonthDay(Date utilDate) {
Instant inst = DateTimeUtils.toInstant(utilDate);
ZonedDateTime dateTime = inst.atZone(ZoneId.systemDefault());
return MonthDay.from(dateTime);
}
The MonthDay class of java.time is what you need, it’s a date without year, or conversely, a month and a day-of-month. Birthdays and other days to remember are the prime example for its use.
Like this:
Date birthday = // ...
Date today = new Date();
if (toMonthDay(today).equals(toMonthDay(birthday))) {
System.out.println("It’s her birthday");
} else {
System.out.println("It’s not her birthday");
}
On Java 6 you need to use the ThreeTen-Backport, the backport of java.time to Java 6 and 7.
I am hesitatingly using ZoneId.systemDefault() to use the JVM’s time zone setting for the conversion. On one hand the Date would normally assume this time zone; on the other hand this is fragile because the setting can be changed at any time from other parts of your program or other programs running in the same JVM. If you know better, by all means give a time zone like for example ZoneId.of("America/Adak")
If using Java 8 or later and the built-in java.time, the conversion is a little bit simpler:
ZonedDateTime dateTime = utilDate.toInstant().atZone(ZoneId.systemDefault());
return MonthDay.from(dateTime);
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
I found the way to call the Month and date-of-month in class Calendar.
here is my solution, I didn't find any other example on this topic, so I'll paste, maybe could help someone in the future.
if you have a more stylish solution, please let me know.
I'll be glad to learn :)
// date of the B-day 31st December
int month = Calendar.DECEMBER;
int date = 31;
boolean status = false;
// Class Date already filled with the date we wanna check.
Date beginDate;
Calendar c = Calendar.getInstance();
c.setTime(beginDate);
int dayOfMonthToCompare = c.get(Calendar.DAY_OF_MONTH);
int monthToCompare = c.get(Calendar.MONTH);
//perform check on day and Month
if(dayOfMonthToCompare == date && monthToCompare == month){
status = true;
}

java last sunday of a month [duplicate]

This question already has answers here:
Get Last Friday of Month in Java
(16 answers)
Closed 4 years ago.
I want to get the last sunday of any given month, and its working to a point however on some inputs if the sunday is the first day of next month it shows that date instead of the same month's last week. Here is what
public static String getLastSunday(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1);
if (leap(year)) {
cal.add(Calendar.DAY_OF_MONTH, -(cal.get(Calendar.DAY_OF_WEEK) - 2));
} else {
cal.add(Calendar.DAY_OF_MONTH, -(cal.get(Calendar.DAY_OF_WEEK)%7 - 1));
}
return cal.getTime().toString().substring(0, 10);
}
calling the function as:
getLastSunday(10, 2015);
returns the output:
Sun Nov 01
Where did I go wrong? Also if it is the leap year, I am not sure if going from -1 to -2 is correct, I researched about it but couldnt find anything useful.
tl;dr
YearMonth.of( 2015 , Month.NOVEMBER ) // Represent the entirety of a specified month.
.atEndOfMonth() // Get the date of the last day of that month.
.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) ) // Move to the previous Sunday, or keep if already Sunday.
Avoid legacy date-time classes
The Question and other Answers are outmoded, using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
Use smart objects, not dumb primitives
Rather than pass year and month as mere integers, pass a single argument of YearMonth class. Doing so ensures valid values, makes your code more self-documenting, and provides type-safety.
YearMonth ym = YearMonth.of( 2015 , Month.NOVEMBER ) ; // Or YearMonth.of( 2015 , 11 ) with sane numbering for month 1-12 for January-December.
The LocalDate class represents a date-only value without time-of-day and without time zone.
Get the last day of the month.
LocalDate endOfMonth = ym.atEndOfMonth() ;
Find the previous Sunday, or keep the end-of-month if it is already a Sunday. Use a TemporalAdjuster found in the TemporalAdjusters class.
LocalDate lastSundayOfPriorMonth = endOfMonth.with( TemporalAdjusters.previousOrSame( DayOfWeek.SUNDAY ) ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
try this way
public static Date getLastSunday( int month, int year ) {
Calendar cal = Calendar.getInstance();
cal.set( year, month + 1, 1 );
cal.add(Calendar.DATE, -1);
cal.add( Calendar.DAY_OF_MONTH, -( cal.get( Calendar.DAY_OF_WEEK ) - 1 ) );
return cal.getTime();
}
source
Try this out (Remember Month value is 0-based. e.g., 0 for January)
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1);
cal.add(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.DATE, -1);
cal.add(Calendar.DATE, -(cal.get(Calendar.DAY_OF_WEEK) -1));
return cal.getTime().toString().substring(0, 10);
So if you want to call this method for Oct 2015, then call like this:
getLastSunday(9, 2015);
Its doing the following things:
1. Setting the passed year and monthe to the calendar object
getLastSunday(9, 2015);
2. Then updates the calendar object to the last day of the current month by using this code:
cal.add(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.DATE, -1);
Then subtracts the number of days from the current date tot the last sunday:
JAVA sets 1 for SUNDAY , 2 for MONDAY and so on. So, if the last day is MONDAY i.e. 2 then it will subtract 1 from it to get the last sunday of the month.
Hope it helps.

Does set of java Calendar always go to future date?

In Java Calendar exists method set. E.g. now is 01/11/2011. If we make like:
Calendar now = new GregorianCalendar();
now.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY);
Calendar will be set to nearest Friday, but for date more than now.
In docs written nothing if always go to the greater date.
Anybody can confirm that?
Thanks.
It always sets it to the given day-of-week within the same week. The first day of the week will depend on the calendar and locale.
For example, using the default calendar on my machine in the UK, Monday is the first day of the week - so setting the day of week to Monday today results in October 31st, whereas setting the day of week to Sunday results in November 6th. However, if I use:
Calendar now = Calendar.getInstance(Locale.US);
now.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(now.getTime());
... then the first day of the week is Sunday, and the result is October 30th.
You can set the first day of the week explicitly using setFirstDayOfWeek.
That method will set the calendar to be Friday of 'this' week. Whether that's in the past or future depends on where in the current week you are at the moment. It is also a locale dependant call, since the first day of the week can be different depending where you are.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
public class Main {
public static void main(String[] args) {
// Replace JVM's ZoneId, ZoneId.systemDefault() with the applicable one e.g.
// ZoneId.of("America/Los_Angeles")
LocalDate today = LocalDate.now(ZoneId.systemDefault());
// Next Sunday
LocalDate nextSun = today.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(nextSun);
// Same (if it's Sunday today) of next Sunday
LocalDate sameOrNextSun = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
System.out.println(sameOrNextSun);
// Previous Sunday
LocalDate previousSun = today.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY));
System.out.println(previousSun);
// Same (if it's Sunday today) of previous Sunday
LocalDate sameOrPreviousSun = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
System.out.println(sameOrPreviousSun);
}
}
Output from a sample run:
2021-07-25
2021-07-18
2021-07-11
2021-07-18
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Categories