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.
Related
I am trying to build a calendar app in Android Studio. Everything works fine despite one little thing. When I have a repeating event (lets say weekly), and after inserting it - which works fine - and I tried to increase it with the function:
calendar.add(Calendar.DAY_OF_YEAR, 7);
The following happens:
It inserts events exactly to the end of the month and in the next year in the same month again, so how can I achieve, that also the month increases and the event will appear next month?
Hope I could explain what I mean.
If you want to add a week (7 days) in your calendar, you should use Calendar.DATE and not Calendar.DAY_OF_YEAR:
Calendar cal = Calendar.getInstance()
cal.add(Calendar.DATE, 7);
Joda-Time
Alternatively you could use the Joda-Time library. The old java.util.Date/.Calendar classes are notoriously troublesome and should be avoided.
If you want only date without time-of-day, use the LocalDate class.
LocalDate today = LocalDate.now(); // Gets today's date using JVM’s current default time zone. You may want to specify a time zone instead, passing a `DateTimeZone` object.
LocalDate weekLater = today.plusWeeks( 1 );
java.time
Java 8 and later comes bundled with the new java.time framework. Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project. Intended to be the successor to Joda-Time. See the Tutorial.
Java 8 technology is not currently available in Android. But there have been some back-port projects. I've heard the back-port may work well in Android but I do not know details.
I am trying to figure out how to make my program count the number of Sundays in a week.
I have tried the following thing:
if (date.DAY_OF_WEEK == date.SUNDAY) {
System.out.println("Sunday!");
}
Yet it does not seem to work?
When I try to System.out.Println the date.DAY_OF_WEEK I get: 7
Does anyone know how I can check if the current calendar date is Sunday?
UPDATE FOR MORE INFORMATION
firt of all the date.DAY_OF_WEEK is a Calendar object!
i made sure to set the Calendar object date to a sunday
The system out print where i get 7 is what it returns to me when i try to run date.DAY_OF_MONTH even if the day it set to a sunday
2nd UPDATE TO ALEX
This is more or less my code
Calendar startDate = Calendar.getInstance();
startDate.set(2012, 12, 02);
if (startDate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
System.out.println("true");
}else {
System.out.println("FALSE");
}
Calendar cal = ...;
if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
System.out.println("Sunday!");
}
Calendar.DAY_OF_WEEK always equals to 7 no matter what instance of Calendar you are using (see this link), it is a constant created to be used with the Calendar.get() method to retrieve the correct value.
It is the call to Calendar.get(Calendar.DAY_OF_WEEK) that will return the real day of week. Besides, you will find useful values in the Calendar class like Calendar.SUNDAY (and the other days and months) in order for you to be more explicit in your code and avoid errors like JANUARY being equal to 0.
Edit
Like I said, the Calendar class does contains useful constants for you to use. There is no month number 12 they start at 0 (see above), so DECEMBER is month number 11 in the Java Date handling.
Calendar startDate = Calendar.getInstance();
startDate.set(2012, Calendar.DECEMBER, 02);
if (startDate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
System.out.println("true");
} else {
System.out.println("FALSE");
}
Will print true of course.
Note: the Joda-Time project is now in maintenance mode. See this answer if you don't have to work with legacy code.
If you have to work with date or time a lot, you might want to try using Joda-Time.
Your code would look something like this:
LocalDate startDate = new LocalDate(2012, 12, 2);
int day = startDate.dayOfWeek().get(); // gets the day of the week as integer
if (DateTimeConstants.SUNDAY == day) {
System.out.println("It's a Sunday!");
}
You can also get a text string from dayOfWeek():
String dayText = startDate.dayOfWeek().getAsText();
will return the string "Sunday".
tl;dr
boolean todayIsSunday = LocalDate.now( ZoneId.of( "America/Montreal" ) ).getDayOfWeek().equals( DayOfWeek.SUNDAY ) ;
java.time
The other Answers are outdated. The modern approach uses java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety. Ditto for Year & YearMonth.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
DayOfWeek
For any LocalDate, you can obtain its day-of-week as a DayOfWeek object. The DayOfWeek enum automatically instantiates seven objects, one for each day of the week.
boolean isSunday = ld.getDayOfWeek().equals( DayOfWeek.SUNDAY ) ;
One Sunday per week
count the number of Sundays in a week.
That would be 1, always one Sunday per week.
If your goal is finding the next Sunday, use a TemporalAdjuster defined in TemporalAdjusters class.
TemporalAdjuster ta = TemporalAdjusters.nextOrSame( DayOfWeek.SUNDAY ) ;
LocalDate nextOrSameSunday = ld.with( ta ) ;
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 brought some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
I need to get the dates for Monday and Friday last week. To do this, i am getting the date of Monday this week and subtracting 7 days. This gives me the date for Monday last week.
To get the date for Friday i have to add 4. This confused me a bit because for some reason the first day of the week is Sunday as opposed to Monday here in the UK.
Anyway, here is how i am getting the dates.
// Get the dates for last MON & FRI
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.add(Calendar.DAY_OF_WEEK, -7);
cal.set(Calendar.HOUR_OF_DAY,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
// Get the date on Friday
cal.add(Calendar.DAY_OF_WEEK, 4);
cal.set(Calendar.HOUR_OF_DAY,23);
cal.set(Calendar.MINUTE,59);
cal.set(Calendar.SECOND,59);
cal.set(Calendar.MILLISECOND,0);
The above works but i am interested if there is anything wrong with the logic. I.e. will it work for Februarys, leap years etc.
Feel free to suggest a better solution/approach.
Thanks
tl;dr
get the dates for Monday and Friday last week
LocalDate // Represent a date only, without a time-of-day, and without a time zone or offset.
.now // Capture the current date as seen through the wall-clock time used by the people of a certain region (a time zone).
(
ZoneId.of( "America/Montreal" )
) // Returns a `LocalDate` object.
.with // Move to another date.
(
TemporalAdjusters.previous( DayOfWeek.MONDAY ) // Returns an implementation of the `TemporalAdjuster` interface.
) // Returns another `LocalDate` object, separate and distinct from our original `LocalDate` object. Per the immutable objects design pattern.
Avoid legacy date-time classes
The other Answers use the troublesome old legacy date-time classes now supplanted by the java.time questions.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
The TemporalAdjuster interface provides for adjustments to move from one date-time value to another. Find handy implementations in the TemporalAdjusters class (note the plural 's'). The previous adjuster finds any specified object from the DayOfWeek enum.
The Question does not exactly define “last week”. Last seven days? Standard Monday-Sunday period? Localized week, such as Sunday-Saturday in the United States? The week prior to today’s week or including today’s partial week?
I will assume the prior seven days were intended.
LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;
LocalDate previousFriday = today.with( TemporalAdjusters.previous( DayOfWeek.FRIDAY ) ) ;
By the way, if you want to consider the initial date if it happens to already be the desired day-of-week, use alternate TemporalAdjuster implementations: previousOrSame or nextOrSame.
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
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 (<26), 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.
Note: For Java 8 and above please take a look at Basil Bourque's answer (link).
Java 8 introduced a new time/date API which offers most of Joda-Time's functionality.
Joda-Time offers really nice methods for problems like that.
Getting the dates for Monday and Friday last week would look something like this using Joda Time:
DateTime today = DateTime.now();
DateTime sameDayLastWeek = today.minusWeeks(1);
DateTime mondayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.MONDAY);
DateTime fridayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.FRIDAY);
You can create DateTime objects from java.util.Date objects and vice versa so it is easy to use with Java dates.
Using the above code with the date
DateTime today = new DateTime("2012-09-30");
results in "2012-09-17" for Monday and "2012-09-21" for Friday, setting the date to
DateTime tomorrow = new DateTime("2012-10-01");
results in "2012-09-24" for Monday and "2012-09-28" for Friday.
You still have start of week set to sunday, which means that Calendar.MONDAY on a saturday is the monday before, while Calendar.MONDAY on a sunday is the next day.
What you need to do is (according to how you want it according to your comment above), to set the start of week to monday.
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.add(Calendar.DAY_OF_WEEK, -7);
...
Beyond that, and that the last second of friday isn't included in the range, your logic seems sound, and shouldn't have trouble with leap years/DST shifts etc.
The only thing I see wrong is that you are in fact testing the range Mo-Fr, and not, as stated, retrieving two specific days. It would be safer to test range Mo-Sa with exclusive upper bound.
You can use TemporalAdjusters to adjust the desired dates/days you are looking for.
Example:
LocalDate today = LocalDate.now();
LocalDate lastMonday = today.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
LocalDate lastFriday = today.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
Is there a way to check if a java Date object is Monday? I see you can with a Calendar object, but date? I'm also using US-eastern date and time if that changes indexing of monday
Something like this will work:
Calendar cal = Calendar.getInstance();
cal.setTime(theDate);
boolean monday = cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY;
You can use Calendar object.
Set your date to calendar object using setTime(date)
Example:
calObj.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY
EDIT: As Jon Skeet suggested, you need to set TimeZone to Calendar object to make sure it works perfect for the timezone.
The question doesn't make sense without two extra pieces of information: a time zone and a calendar system.
A Date object just represents an instant in time. It happens to be Wednesday in the Gregorian calendar in my time zone - but for some folks to the east of me, it's already Thursday. In other calendar systems, there may not even be such a concept of "Monday" etc.
The calendar system part is probably not a problem, but you will need to work out which time zone you're interested in.
You can then create a Calendar object and set both the time zone and the instant represented - or, better, you could use Joda Time which is a much better date/time API. You'll still need to think about the same questions, but your code will be clearer.
You should use Calendar object for these checks. Date has weak timezones support. In one timezone this Date can be Monday, and in another timezone it is still Sunday.
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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
Use Instant to represent a moment:
Instant instant = Instant.now();
System.out.println(instant); // A sample output: 2021-07-03T09:07:37.984Z
An Instant represents an instantaneous point on the timeline in UTC. The Z in the output is the timezone designator for a zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
However, if you have got an object of java.util.Date, convert it to Instant e.g.
Date date = new Date(); // A sample date
Instant instant = date.toInstant();
Convert Instant to ZonedDateTime representing Date-Time in your timezone e.g.
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/New_York"));
Check if the Date-Time falls on Monday e.g.
System.out.println(zdt.getDayOfWeek() == DayOfWeek.SUNDAY);
Demo:
import static java.time.DayOfWeek.SUNDAY;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdt.getDayOfWeek() == SUNDAY);
}
}
Output:
false
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.
What time is the start of a day, say 01/01/2010?
Is it 00:00:00:000 ? or is that midnight?
[edit]
It might be a stupid question but I'm confused because I used Calendar.set(Calendar.HOUR, 0) but this gives me a time of 12:00:00.
and now I've realised I should be using HOUR_OF_DAY
The start of the day isn't always midnight. It can depend on the time zone and date. (If the clock moves forward an hour at the start of the day, it will start at 1am.)
That's why Joda-Time has things like LocalDate.toDateTimeAtStartOfDay - and they're well worth using.
But yes, normally it's at 00:00:00 which is midnight. (This can also be formatted as "12am" depending on your locale etc.)
java.time
Normally, the start of the date is 00:00 hours but it may vary because of DST. Therefore, instead of assuming it to be 00:00 hours, the safest option is to use LocalDate#atStartOfDay(ZoneId zone).
Demo:
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("01/01/2010", dtf);
// In JVM's timezone
ZonedDateTime startOfDay = date.atStartOfDay(ZoneId.systemDefault());
System.out.println(startOfDay);
// In custom timezone
startOfDay = date.atStartOfDay(ZoneId.of("Africa/Johannesburg"));
System.out.println(startOfDay);
}
}
Output:
2010-01-01T00:00Z[Europe/London]
2010-01-01T00:00+02:00[Africa/Johannesburg]
Learn more about the 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.
ZonedDateTime from java.time
Like Arvind Kumar Avinash already does in a good answer, I recommend that you use java.time, the modern Java date and time API, for your date and time work.
If you had got a LocalDate or a string holding a date without time of day, that answer shows you how to get the start of the day (the first moment of the day). If you had already got a ZonedDateTime, you may simply use its truncatedTo method. Let’s take one of those interesting examples where the clocks are turned forward at 00:00 so the first moment of the day is 01:00:
ZonedDateTime zdt = ZonedDateTime.of(
2000, 9, 17, 15, 45, 56, 789000000, ZoneId.of("Asia/Dili"));
System.out.println("We got date and time: " + zdt);
ZonedDateTime startOfDay = zdt.truncatedTo(ChronoUnit.DAYS);
System.out.println("Start of day is: " + startOfDay);
Output:
We got date and time: 2000-09-17T15:45:56.789+09:00[Asia/Dili]
Start of day is: 2000-09-17T01:00+09:00[Asia/Dili]
What went wrong in your code?
You’ve already said it in an edit to the question, but it deserves to be mentioned in an answer too: Calendar.HOUR refers to, from the documentation:
Field number for get and set indicating the hour of the morning or
afternoon. HOUR is used for the 12-hour clock (0 - 11). …
So if your Calendar was already holding a time in the afternoon (12 noon or later), setting HOUR to 0 gives you 12 noon (12:00 on a 24 hour clock), not 12 midnight (00:00 on a 24 hour clock). Except that the time of the hour may still be non-zero, so you may also get, for example, 12:34:45.567. The Calendar class was cumbersome to work with.
In any case the Calendar class was poorly designed and is long outdated, so you shouldn’t need to worry; just don’t use that class anymore.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of Calendar.HOUR.