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….
Related
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.
This question already has answers here:
Why is January month 0 in Java Calendar?
(18 answers)
Closed 2 years ago.
Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));
After the execution of the above snippet, month gets a value of 10 instead of 11. How come?
Months are indexed from 0 not 1 so 10 is November and 11 will be December.
They start from 0 - check the docs
As is clear by the many answers: the month starts with 0.
Here's a tip: you should be using SimpleDateFormat to get the String-representation of the month:
Calendar rightNow = Calendar.getInstance();
java.text.SimpleDateFormat df1 = new java.text.SimpleDateFormat("MM");
java.text.SimpleDateFormat df2 = new java.text.SimpleDateFormat("MMM");
java.text.SimpleDateFormat df3 = new java.text.SimpleDateFormat("MMMM");
System.out.println(df1.format(rightNow.getTime()));
System.out.println(df2.format(rightNow.getTime()));
System.out.println(df3.format(rightNow.getTime()));
Output:
11
Nov
November
Note: the output may vary, it is Locale-specific.
As several people have pointed out, months returned by the Calendar and Date classes in Java are indexed from 0 instead of 1. So 0 is January, and the current month, November, is 10.
You might wonder why this is the case. The origins lie with the POSIX standard functions ctime, gmtime and localtime, which accept or return a time_t structure with the following fields (from man 3 ctime):
int tm_mday; /* day of month (1 - 31) */
int tm_mon; /* month of year (0 - 11) */
int tm_year; /* year - 1900 */
This API was copied pretty much exactly into the Java Date class in Java 1.0, and from there mostly intact into the Calendar class in Java 1.1. Sun fixed the most glaring problem when they introduced Calendar – the fact that the year 2001 in the Gregorian calendar was represented by the value 101 in their Date class. But I'm not sure why they didn't change the day and month values to at least both be consistent in their indexing, either from zero or one. This inconsistency and related confusion still exists in Java (and C) to this day.
Months start from zero, like indexes for lists.
Therefore Jan = 0, Feb = 1, etc.
From the API:
The first month of the year is JANUARY
which is 0; the last depends on the
number of months in a year.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html
tl;dr
LocalDate.now() // Returns a date-only `LocalDate` object for the current month of the JVM’s current default time zone.
.getMonthValue() // Returns 1-12 for January-December.
Details
Other answers are correct but outdated.
The troublesome old date-time classes had many poor design choices and flaws. One was the zero-based counting of month numbers 0-11 rather than the obvious 1-12.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
Now in maintenance mode, the Joda-Time project also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.
Months 1-12
In java.time the month number is indeed the expected 1-12 for January-December.
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.
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(!).
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue(); // Returns 1-12 as values.
If you want a date-time for a time zone, use ZonedDateTime object in the same way.
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue(); // Returns 1-12 as values.
Convert legacy classes
If you have a GregorianCalendar object in hand, convert to ZonedDateTime using new toZonedDateTime method added to the old class. For more conversion info, see Convert java.util.Date to what “java.time” type?
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue(); // Returns 1-12 as values.
Month enum
The java.time classes include the handy Month enum, by the way. Use instances of this class in your code rather than mere integers to make your code more self-documenting, provide type-safety, and ensure valid values.
Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.
The Month enum offers useful methods such as generating a String with the localized name of the month.
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
cal.get(Calendar.MONTH) + 1;
The above statement gives the exact number of the month. As get(Calendar.Month) returns month starting from 0, adding 1 to the result would give the correct output. And keep in mind to subtract 1 when setting the month.
cal.set(Calendar.MONTH, (8 - 1));
Or use the constant variables provided.
cal.set(Calendar.MONTH, Calendar.AUGUST);
It would be better to use
Calendar.JANUARY
which is zero ...
Hi i have some problem with DAY_OF_WEEK. After research but don't know why.
Input date is :
30/01/2016 - SATURDAY
After run :
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
Output :
31/01/2016 - SUNDAY(Wrong).
I want it must 30/01/2016 - SATURDAY,
Please help me ?
try by passing Date
Calendar calendar = Calendar.getInstance;
calendar.set(2016, Calendar.JANUARY, 30);
or try this too
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
for(int i=0; i<7; i++)
{
System.out.print("Start Date : " + c.getTime() + ", ");
c.add(Calendar.DAY_OF_WEEK, 6);
}
tl;dr
LocalDate.of( 2016 , Month.JANUARY , 30 )
.with( TemporalAdjusters.next( DayOfWeek.SATURDAY ) )
2016-02-06
java.time
The modern approach uses java.time classes rather than the troublesome old Calendar class that is now legacy.
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.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone 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 ) ;
Adjuster
To move from one date to another, use a TemporalAdjuster implementation found in TemporalAdjusters class. Specify the desired day-of-week using [DayOfWeek][2] enum.
LocalDate previousOrSameMonday = today.with( TemporalAdjusters.previousOrSame( DayOfWeek.SATURDAY ) ) ;
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….
I want to convert milliSeconds in long format to Gregorian Calendar.
By searching in the web, i use the code below:
public static String getStringDate(int julianDate){
GregorianCalendar gCal = new GregorianCalendar();
Time gTime = new Time();
gTime.setJulianDay(julianDate);
gCal.setTimeInMillis(gTime.toMillis(false));
String gString = Utils.getdf().format(gCal.getTime());
return gString;
}
public static SimpleDateFormat getdf(){
return new SimpleDateFormat("yyyy-MM-dd, HH:MM",Locale.US);
}
Yes, the code works but i find that only the date and the hour are correct but there are errors on minutes. Say if the thing happens on 2014-11-06, 14:00, it will give me 2014-11-06, 14:11. I want to know are there any solutions to modify it or it is not recommended to convert time into Gregorian Calendar. Many thanks!
The problem actually is very simple,
modify SimpleDateFormat("yyyy-MM-dd, HH:MM",Locale.US) with
SimpleDateFormat("yyyy-MM-dd, HH:mm",Locale.getDefault());
will solve the problem
tl;dr
Instant.ofEpochMilli( millis ) // Convert count-from-epoch into a `Instant` object for a moment in UTC.
.atZone( ZoneId.of( "Pacific/Auckland" ) ) // Adjust from UTC to a particular time zone. Same moment, different wall-clock time. Renders a `ZonedDateTime` object.
.format( // Generate a String in a particular format to represent the value of our `ZonedDateTime` object.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd, HH:mm" )
)
java.time
The modern approach uses the java.time classes instead of those troublesome legacy classes.
Convert your count of milliseconds since the epoch reference of first moment of 1970 (1970-01-01T00:00Z) to a Instant object. Be aware that Instant is capable of finer granularity of nanoseconds.
Instant instant = Instant.ofEpochMilli( millis ) ;
That moment is in UTC. To adjust into another time zone, apply a ZoneId to get a ZonedDateTime.
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, so your results may vary. Better to specify your desired/expected time zone 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( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Generate a string in your desired format using a DateTimeFormatter object.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd, HH:mm" , Locale.US ) ;
String output = zdt.format( f ) ;
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….
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')) );