Check if Date is the next day after 00:00 am - android

I have a streak counter that increases if an action in the app is done every day anew. I want to check it upon opening of the app, what is the easiest way?
I know I can just check in a Calendar or Date object, if it's yesterday+1, like here
Check if a date is "tomorrow" or "the day after tomorrow"
But that is not considering the time, right? Because if the action is done on 24.02. 7AM, then it would have to be 25.02. 7AM+ (24hrs) for it to work?

I know I can just check in a Calendar or Date object, if it's
yesterday+1 ...
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.
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.
But that is not considering the time, right? Because if the action is
done on 24.02. 7AM, then it would have to be 25.02. 7AM+ (24hrs) for
it to work?
The java.time API (the modern date-time API) provides you with LocalDateTime to deal with local date and time (i.e. the date and time of a place and not requiring comparing it with the date and time of another place and hence not dealing with the timezone). However, when it comes to comparing it with the date and time of another place, not in the same timezone, you need ZonedDateTime (to automatically adjust date & time object as per the DST) or OffsetDateTime (to deal with ` fixed timezone offset) etc. Given below is an overview of java.time types:
Demo:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Main {
public static void main(String args[]) {
LocalDate date = LocalDate.of(2020, 2, 23);
LocalTime time = LocalTime.of(7, 0);
LocalDateTime ldt = LocalDateTime.of(date, time);
System.out.println(ldt);
LocalDateTime afterTenHoursTwentyMinutes = ldt.plusHours(10).plusMinutes(20);
LocalDateTime tomorrow = ldt.plusDays(1);
LocalDateTime theDayAfterTomorrow = ldt.plusDays(2);
System.out.println(afterTenHoursTwentyMinutes);
System.out.println(tomorrow);
System.out.println(theDayAfterTomorrow);
if (!afterTenHoursTwentyMinutes.isAfter(theDayAfterTomorrow)) {
System.out.println("After 10 hours and 20 minutes, the date & time will not go past " + tomorrow);
} else {
System.out.println("After 10 hours and 20 minutes, the date & time will go past " + tomorrow);
}
}
}
Output:
2020-02-23T07:00
2020-02-23T17:20
2020-02-24T07:00
2020-02-25T07:00
After 10 hours and 20 minutes, the date & time will not go past 2020-02-24T07:00
Learn more about the modern date-time API from Trail: Date Time.

Related

check if saved date is one day before to current date android

Okay so i read this : Check date with todays date
#sudocode gave this code :
Calendar c = Calendar.getInstance();
// set the calendar to start of today
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
// and get that as a Date
Date today = c.getTime();
// or as a timestamp in milliseconds
long todayInMillis = c.getTimeInMillis();
// user-specified date which you are testing
// let's say the components come from a form or something
int year = 2011;
int month = 5;
int dayOfMonth = 20;
// reuse the calendar to set user specified date
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
// and get that as a Date
Date dateSpecified = c.getTime();
// test your condition
if (dateSpecified.before(today)) {
System.err.println("Date specified [" + dateSpecified + "] is before today [" + today + "]");
} else {
System.err.println("Date specified [" + dateSpecified + "] is NOT before today [" + today + "]");
}
But imagine the saved date was 28/01/2018 11:00pm and i run this at 28/01/2018 11:15pm so this code will tell me that saved date is before the current date.
What i want is, the code should only run a function if the saved date is more than one day old... (not 24 hours but actually a day or more old) lets say saved date it 27/01/2018 11:00pm and current date is 28/01/2018 then it should run.. how do i implement this ?
You can do something like this:
public long daysBetween(Calendar first, Calendar second) {
long diffInMillis = second.getTimeInMillis() - first.getTimeInMillis();
return TimeUnit.MILLISECONDS.toDays(diffInMillis);
}
And then just ask if the difference is >= 1. This also assumes that second >= first.
This example is using the standard Java (7) date stuff, so you should be able to use it in your project.
tl;dr
Determining dates requires a time zone.
Use only java.time classes, never legacy java.util.Date, Calendar, java.sql.Date, java.sql.Timestamp, etc.
myResultSet.getObject(
… ,
Instant.class
) // Retrieve a `java.time.Instant` from a column of type akin to the SQL-standard `TIMESTAMP WITH TIME ZONE`.
.atZone(
ZoneId.of( "Pacific/Auckland" )
)
.toLocalDate()
.isEqual(
LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )
)
Avoid legacy date-time classes
The terrible Date and Calendar legacy classes were supplanted years ago by the modern java.time classes.
Time zones
Your Question ignores the crucial issue of time zone. For any given moment, the date and time-of-day both vary around the globe by time zone. You cannot talk about dates without talking about time 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][2] explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-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 JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
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.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Never assume 00:00:00
Also, do not assume the day starts at 00:00:00. Because of anomalies such as Daylight Saving Time (DST), the day may start at another time, such as 01:00:00. Let java.time determine the first moment of the day. Specify a time zone to yield a ZonedDateTime object representing a specific moment.
ZonedDateTime startOfToday = LocalDate.now( z ).atStartOfDay( z ) ;
ZonedDateTime startOfYesterday = startOfToday.toLocalDate().minusDays( 1 ).atStartOfDay( z ) ;
For querying database, it is often best to use UTC values. To adjust from our time zone to UTC, simply extract a Instant.
Instant start = startOfToday.toInstant() ;
Instant stop = startOfYesterday.toInstant() ;
Ready to query database. Using Half-Open approach here where beginning is inclusive while ending is exclusive. So, do not use SQL BETWEEN.
// SQL for SELECT WHERE when_field >= ? AND when_field < ?
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;
Comparing dates
If you just want to check the age of a retrieved moment, retrieve an Instant.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Apply a time zone to get a ZonedDateTime. Then extract the date-only value.
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDate ld = zdt.toLocalDate() ; // Extract the date-only value.
Compare to today's date.
LocalDate yesterday = LocalDate.now( z ).minusDays( 1 ) ; // Subtract one day from today to get yesterday.
Boolean retrievedDateIsYesterday = ld.isEqual( yesterday ) ;
If you work much with spans-of-time, see the Interval and LocalDateRange classes in the ThreeTen-Extra project linked below.
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, Java SE 10, Java SE 11, and later - 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
Most 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.

Calendar get time issue

I have a small application which simply sets the time and date of a Calendar and then retrieves it.
Currently when using my application on devices up to API24 its retrieves the correct date which was originally set. But if you run the application on a device higher than API 24 then the date returned is one day later than the desired result.
My code as below
Setting the date of the calendar....
myCalendar.set(Calendar.YEAR, 2018 );
myCalendar.set(Calendar.DAY_OF_MONTH, 3);
myCalendar.set(Calendar.MONTH, 0);
myCalendar.set(Calendar.HOUR, 18);
myCalendar.set(Calendar.MINUTE, 30);
Retrieving the date
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dates = sdf.format(myCalendar.getTime());
StringTokenizer revDate = new StringTokenizer(dates, "/");
String txtDays = revDate.nextToken();
String txtMonths = revDate.nextToken();
String txtYears = revDate.nextToken();
String reversedDate = txtDays + txtMonths + txtYears;
On phones below API 24 we receive the correct date 03/01/2018 on API 24 above I receive 04/01/2018
I've tested my application on multiple virtual devices and real phones, all using the same time zone its only when using API 24 above that this strange issue occurs.
Thanks
I should like to contribute the modern version of your code. Barns’ answer is correct and should make sure your code behaves as it should. But I prefer:
LocalDateTime myDateTime = LocalDateTime.of(2018, Month.JANUARY, 3, 18, 30);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMuuuu");
String reversedDate = myDateTime.format(dtf);
This produces a reversedDate of 03012018 to denote 3 January 2018. If you needed the order of day-of-month, month and year reversed somehow, just modify the order in the format pattern string, for example uuuuMMdd or MMdduuuu.
I recommend the modern classes. Even though on not-too-brand-new Android devices, Calendar and SimpleDateFormat are what you get built-in, those classes are long outmoded and the latter in particular notoriously troublesome. So in my snippet I am assuming you have added ThreeTenABP to you Android project to allow you to use JSR 310, also known as java.time, the modern Java date and time API. This is so much nicer to work with. Import org.threeten.bp.LocalDateTime, org.threeten.bp.Month and org.threeten.bp.format.DateTimeFormatter. Also StringTokenizer is a legacy class. Its documentation says “It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.”
What went wrong in your code?
You haven’t given us a complete and reproducible example, so I cannot be sure, but strongly I suspect that you see the incorrect date when your code is running in the afternoon, that is at 12 noon or later in the myCalendar’s time zone (typically the JVM’s time zone, in turn typically your local time zone). Very likely myCalendar was created with the current time (Calendar.getInstance() and new GregorianCalendar(), for example, do this). In the afternoon it is obviously created with a time in PM. Then when you call myCalendar.set(Calendar.HOUR, 18), this tries to set the hour within PM, but since the hour is 18, this overflows into AM of the following day, becoming 6 AM the next day.
Links
Oracle tutorial: Date Time, explaining how to use JSR-310/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, where the modern date and time API was first described.
You should use "HOUR_OF_DAY" instead of "HOUR" when you set the time and you are using 24-hr system.
Try this:
myCalendar.set(Calendar.YEAR, 2018 );
myCalendar.set(Calendar.DAY_OF_MONTH, 3);
myCalendar.set(Calendar.MONTH, 0);
myCalendar.set(Calendar.HOUR_OF_DAY, 18);
myCalendar.set(Calendar.MINUTE, 30);
According to JAVA Docs:
HOUR_OF_DAY
public static final int HOUR_OF_DAY
Field number for get and set indicating the hour of the day.
HOUR_OF_DAY is used for the 24-hour clock. E.g., at 10:04:15.250 PM
the HOUR_OF_DAY is 22.
HOUR
public static final int HOUR
Field number for get and set indicating the hour of the morning or
afternoon. HOUR is used for the 12-hour clock (0 - 11). Noon and
midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM the
HOUR is 10.
I think you should use getInstance() method of calendar class because Calendar.getInstance() method gets a calendar using the specified time zone and specified locale.
for eg:
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date dat = Calendar.getInstance().getTime();
String s3 = df.format(dat);
this works perfectly fine with my program and gives me desired result along with manipulation of date in the desired format.

Android: Compare time in this format `yyyy-mm-dd hh:mm:ss` to the current moment

I want to get the current time on the device in the format: 2013-10-17 15:45:01 ?
The server sends me the date of an object in the format above as a string. Now i want to get the phones current time and then check if there is a difference of say more than 5 minutes?
So A: How can i get the devices current time in this fomat: 2013-10-17 15:45:01
B how can I work out the difference between the two.
You can use SimpleDateFormat to specify the pattern you want:
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new java.util.Date())
However, if you just want to know whether the time difference is within a certain threshold, you should probably just compare long values. If your threshold is 5 minutes, then this is 5 * 60 * 1000 milliseconds so you can use the same SimpleDateFormat by calling it's parse method and check the long values.
Example:
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2013-10-13 14:54:03").getTime()
Date currentDate = new Date(); will initialize a new date with the current time. In addition, convert the server provided time and take the difference.
String objectCreatedDateString = "2013-10-17 15:45:01";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date objectCreatedDate = null;
Date currentDate = new Date();
try
{objectCreatedDate = format.parse(objectCreatedDateString);}
catch (ParseException e)
{Log.e(TAG, e.getMessage());}
int timeDifferential;
if (objectCreatedDate != null)
timeDifferential = objectCreatedDate.getMinutes() - currentDate.getMinutes();
tl;dr
Duration.between( // Calculate time elapsed between two moments.
LocalDateTime // Represent a date with time-of-day but lacking the context of a time zone or offset-from-UTC.
.parse( "2013-10-17 15:45:01".replace( " " , "T" ) )
.atOffset( ZoneOffset.UTC ) // Returns an `OffsetDateTime` object.
.toInstant() , // Returns an `Instant` object.
Instant.now() // Capture the current moment as seen in UTC.
)
.toMinutes()
> 5
java.time
The other Answers are outdated, using terrible classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Parse your incoming string.
String input = "2013-10-17 15:45:01" ;
Modify the input to comply with ISO 8601. I suggest you educate the publisher of your data about the ISO 8601 standard.
String inoutModified = input.replace( " " , "T" ) ;
Parse as a LocalDateTime because this input lacks an indicator of the intended offset or time zone.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
I assume that input was intended to represent a moment as seen in UTC, with an offset of zero hours minutes seconds. If so, educate the publisher of your data about appending a Z on the end to so indicate, per ISO 8601.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
Extract an object of the simpler class, Instant. This class is always in UTC.
Instant then = odt.toInstant() ;
Get current moment as seen in UTC.
Instant now = Instant.now() ;
Calculate the difference.
Duration d = Duration.between( then , now ) ;
Get duration as total whole minutes.
long minutes = d.toMinutes() ;
Test.
if ( minutes > 5 ) { … }
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….
Use SimpleDateFromat Class
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dateFormatter.format(date);
Also check this documentation
If you can ask the server to send you an RFC3339 compliant date/time string, then Here is a simple answer to both of your questions:
public String getClientTime() {
Time clientTime = new Time().setToNow();
return clientTime.format("%Y-%m-%d %H:%M:%S");
}
public int diffClientAndServerTime(String svrTimeStr) {
Time svrTime = new Time();
svrTime.parse3339(svrTimeStr);
Time clientTime = new Time();
clientTime.setToNow();
return svrTime.compare( svrTime, clientTime);
}

Get timestamp for start of day

I am storing times/dates in a database using a unix timestamp.
I want to then get all the instances on certain day so I therefore need to calculate the timestamp for the start of the day in order to query the database.
I have done a similar thing in php by passing mktime the values for the day/month/year from a date object and setting hour and minute to zero. There doesn't seem to be similar functions for this in java/android (the functions for getting the specific parts of date are deprecated)
Can anyone give some guidance on this? Thanks
Edit:
Ok so I realised this might work:
public static int startOfDay(Timestamp time) {
Calendar cal = dateToCalendar(new Date(time.getTime()));
cal.add(Calendar.HOUR_OF_DAY, -Calendar.HOUR_OF_DAY);
cal.add(Calendar.MINUTE, -Calendar.MINUTE);
cal.add(Calendar.SECOND, -Calendar.SECOND);
Log.i("Time", cal.getTime().toString());
return (int) cal.getTimeInMillis()/1000;
}
However when I ran this just now I got:
Sat Dec 15 01:24:00 GMT 2012
The seconds are right but the hour and minute are wrong??
When dealing with time, you should always consider time zones. You database timestamps should be always stored in one time zone (e.g. UTC). Your computation should then consider that users can be in different time zones and that they can change time zones.
If you want to compute start of the day in the time zone the user has currently set in his phone. Create the Calendar instance with:
Calendar cal = Calendar.getInstance();
To get the instance for a specific time zone use:
// use UTC time zone
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Then set the beginning of the day:
cal.setTime(time); // compute start of the day for the timestamp
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
public static int startOfDay(Timestamp time) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time.getTime());
cal.set(Calendar.HOUR_OF_DAY, 0); //set hours to zero
cal.set(Calendar.MINUTE, 0); // set minutes to zero
cal.set(Calendar.SECOND, 0); //set seconds to zero
Log.i("Time", cal.getTime().toString());
return (int) cal.getTimeInMillis()/1000;
}
tl;dr
ZoneId z = ZoneId.of( "America/Montreal" );
long secondsSinceEpoch = ZonedDateTime.now( z ).toLocalDate().asStartOfDay( z ).toEpochSecond() ;
Details
The accepted Answer by Tomik is correct but outdated. The troublesome old legacy date-time classes have been supplanted by the java.time classes.
As that Answer advised, you must consider time zone when getting the start of a day. 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" );
ZonedDateTime zdt = ZonedDateTime.now( z );
Getting the first moment of the day requires going through LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate today = zdt.toLocalDate();
ZonedDateTime zdtTodayStart = today.atStartOfDay( z );
Note that we let java.time determine the start of day rather than assuming and hard-coding 00:00:00. Because of Daylight Saving Time (DST) and other anomalies, the day may start at another time such as 01:00:00.
Apparently, by unix timestamp you mean a count of whole seconds since the first moment of 1970 in UTC. The ZonedDateTime class has a method to give you that number. Note this may mean data loss as the ZonedDateTime may have a fraction of a second with resolution of nanoseconds.
long secondsSinceEpoch = zdtTodayStart.toEpochSecond();
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, Java SE 10, Java SE 11, and later - 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
Most 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….

Get first Monday after certain date?

If my app received a certain date, how can I find out the date of first next Monday?
For example, I get the date 28 Sep 2011 and I have to find out the date of the first Monday after this date.
Do like this:
GregorianCalendar date = new GregorianCalendar( year, month, day );
while( date.get( Calendar.DAY_OF_WEEK ) != Calendar.MONDAY )
date.add( Calendar.DATE, 1 );
You can now extract the year, day and month from date. Remember that month is 0 based (e.g. January = 0, Febuary = 1, etc.) and day is not.
tl;dr
LocalDate.now( ZoneId.of( "America/Montreal" ) ) // Capture the current date as seen by the people in a certain region (time zone).
.with( TemporalAdjusters.next( DayOfWeek.WEDNESDAY ) ) ; // Move to the following Wednesday.
Avoid .Date/.Calendar
The java.util.Date & .Calendar classes bundled with Java/Android are notoriously troublesome. Avoid them.
java.time – LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
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.
The time zone is crucial in determining the day and day-of-week. Use proper time zone names, never the 3 or 4 letter codes.
If you ignore time zone, the JVM’s current default time zone will be applied implicitly. This means different outputs when moving your app from one machine to another, or when a sys admin changes the time zone of host machine, or when any Java code in any thread of any app within the same JVM decides to call setDefault even during your app‘s execution.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
Use a TemporalAdjuster to get next day-of-week. We can use an implementation in the TemporalAdjusters (note the plural 's') class: next( DayOfWeek ). Pass an object from the handy DayOfWeek enum.
LocalDate nextWednesday = today.with( TemporalAdjusters.next( DayOfWeek.WEDNESDAY ) );
If you wanted today to be found if it is a Wednesday, then call the similar adjuster TemporalAdjusters.nextOrSame( DayOfWeek ).
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….
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact as history.
Here is example code using Joda-Time 2.7.
Get the time zone you desire/expect. If working in UTC, use the constant DateTimeZone.UTC.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
Get the date-time value you need. Here I am using the current moment.
DateTime dateTime = DateTime.now( zone );
Specify the future day-of-week you want. Note that Joda-Time uses the sensible # 1 for first day of week, rather than zero-based counting found in java.util.Calendar. First day of week is Monday, per international norms and standards (not Sunday as is common in United States).
int dayOfWeek = DateTimeConstants.SATURDAY;
The withDayOfWeek command may go back in time. So we use a ternary operator (?:) to make sure we go forwards in time by adding a week as needed.
DateTime future = ( dateTime.getDayOfWeek() < dayOfWeek )
? dateTime.withDayOfWeek( dayOfWeek )
: dateTime.plusWeeks( 1 ).withDayOfWeek( dayOfWeek );
You may want to adjust the time-of-day to the first moment of the day to emphasize the focus on the day rather than a particular moment within the day.
future = future.withTimeAtStartOfDay(); // Adjust time-of-day to first moment of the day to stress the focus on the entire day rather than a specific moment within the day. Or use `LocalDate` class.
Dump to console.
System.out.println( "Next day # " + dayOfWeek + " after " + dateTime + " is " + future );
When run.
Next day # 6 after 2015-04-18T16:03:36.146-04:00 is 2015-04-25T00:00:00.000-04:00
LocalDate
If you only care about the date without any time of day, you can write similar code with the LocalDate class rather than DateTime. The "Local" means the date could apply to any locality, rather than having a specific time zone.
LocalDate localDate = new LocalDate( 2011 , 9 , 28 );
int dayOfWeek = DateTimeConstants.MONDAY;
LocalDate future = ( localDate.getDayOfWeek() < dayOfWeek )
? localDate.withDayOfWeek( dayOfWeek )
: localDate.plusWeeks( 1 ).withDayOfWeek( dayOfWeek );
When run.
Next day # 1 after 2011-09-28 is 2011-10-03
Get Next Monday from the date given.
//code provided by MadProgrammer at http://stackoverflow.com/questions/24177516/get-first-next-monday-after-certain-date/24177555#24177555
Calendar date1 = Calendar.getInstance();
date1.set(2014, 05, 12);
while (date1.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
date1.add(Calendar.DATE, 1);
}
System.out.println(date1.getTime());
Which outputted...
Mon Jun 16 16:22:26 EST 2014
I recently developed Lamma which is designed to solve this use case. Simply call next(DayOfWeek.MONDAY) on io.lamma.Date object will return the next Monday.
System.out.println(new Date(2014, 6, 27).next(DayOfWeek.MONDAY)); // Date(2014,6,30)
you can use strtotime():
date('Y-m-d H:i:s', strtotime( "Next Monday", strtotime('28 Sep 2011')) );

Categories

Resources