Java Timestamp - Adding five minutes - java

looking for some help with a bit of Java code i'm working on, i have the following code which prints out the date and time:
Date dNow = new Date( ); // Instantiate a Date object
SimpleDateFormat ft = new SimpleDateFormat ("MMM d, yyyy k:mm:ss"); // Time at server
Result: Mar 15, 2013 10:19:48
I'm creating a javascript counter to work from this number and countdown from 5 minutes. So i need to add 5 minues to the current date time in Java.
So, if the current date time is: Mar 15, 2013 10:19:48
I need to add 5 minutes to Java so that it prints out: Mar 15, 2013 10:24:48
Any ideas?

Instead of starting with
new Date()
start with
new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5))
This will give you a Date instance that represents your required point in time. You don't need to change any other part of your code.

Ignoring Dates and focusing on the question.
My preference is to use java.util.concurrent.TimeUnit since it adds clarity to my code.
In Java,
long now = System.currentTimeMillis();
5 minutes from now using TimeUtil is:
long nowPlus5Minutes = now + TimeUnit.MINUTES.toMillis(5);
Reference: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html

You should use Calendar class to manipulate Date and time:
The Calendar class is an abstract class that provides methods for
converting between a specific instant in time and a set of calendar
fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for
manipulating the calendar fields, such as getting the date of the next
week
Date dNow = new Date( ); // Instantiate a Date object
Calendar cal = Calendar.getInstance();
cal.setTime(dNow);
cal.add(Calendar.MINUTE, 5);
dNow = cal.getTime();

tl;dr
Instant.now()
.plusSeconds( TimeUnit.MINUTES.toSeconds( 5 ) )
.toString()
2017-01-23T03:11:53.763Z
Details
The other Answers are outdated as of Java 8. The troublesome old date-time classes are now legacy, supplanted by the java.time classes.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now();
This class can do math such as adding a number of seconds. We can use the TimeUnit enum to covert our desired five minutes into a number of seconds.
long seconds = TimeUnit.MINUTES.toSeconds( 5 );
Instant fiveMinutesLater = instant.plusSeconds( seconds );
To generate a string in standard ISO 8601 format, call toString.
String output = fiveMinutesLater.toString();
To generate strings in other formats, use the ZonedDateTime class and DateTimeFormatter class. Search Stack Overflow for many examples and discussions of those classes.
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 and 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 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.

Use this ...
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime());
calendar.add(Calendar.MINUTE, 5);
System.out.println(calendar.getTime());

Date dNow = new Date(System.currentTimeMillis()+5*60*1000)
SimpleDateFormat ft = new SimpleDateFormat ("MMM d, yyyy k:mm:ss");
System.out.println(ft.format(dNow));
with the help of deprecated method getMinutes(),setMinutes(int)
Date dNow = new Date( ); // Instantiate a Date object
int mm = dNow.getMinutes();
dNow.setMinutes(mm+5);

Java dates use Unix time in milliseconds. So you either calculate how much 5 minutes are in milliseconds and add them to your date or use the Calendar class which does it for you.

You can try this one best performance
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(System.currentTimeMillis());
gc.add(Calendar.MINUTE, -5);
System.out.println(new java.util.Date().getTime());
System.out.println(new java.util.Date(gc.getTime().getTime()).getTime());

Related

Find next quarter end date given previous quarter end date using Java

I am having quarter end date of last quarter let it be 30-09-20 , the requirement is to find end date of next quarter i.e 31-12-20. I am using below code to do the same but is it giving wrong output in some scenarios. This solution should be correct for all quarters.
String str = "30-09-20";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yy");
Date date = format.parse(str);
Date newDate = DateUtils.addMonths(date, 3);
System.out.println(newDate);//Dec 30 - It should be 31 Dec
To answer your question, I think you are looking for this :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate end = LocalDate.parse("30-09-20", formatter)
.plusMonths(3) // add three months to your date
.with(TemporalAdjusters.lastDayOfMonth()); // with the last day of the month
Note: don't use the legacy Date library, you tagged your question Java-8 which mean you can use java-time API.
Get last day of current quarter
#deHaar have reason, to get the end date of curent quarter, I would suggest to use :
public LocalDate lastDayFromDateQuarter(String date) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate ld = LocalDate.parse(date, formatter);
int quarter = ld.get(IsoFields.QUARTER_OF_YEAR); // Get the Quarter, 1, 2, 3, 4
// Then create a new date with new quarter * 3 and last day of month
return ld.withMonth(quarter * 3).with(TemporalAdjusters.lastDayOfMonth());
}
Get last day of next quarter
To get the last day of the next quarter, then you just can add three months to your date like so :
public static LocalDate lastDayFromDateQuarter(String date) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate ld = LocalDate.parse(date, formatter);
int quarter = ld.get(IsoFields.QUARTER_OF_YEAR);
return ld.withMonth(quarter * 3)
.plusMonths(3)
.with(TemporalAdjusters.lastDayOfMonth());
}
tl;dr
Use YearQuarter class from ThreeTen-Extra.
YearQuarter // A class available in the ThreeTen-Extra library.
.from( // Factory method rather than calling `new`.
LocalDate.of( 2020 , Month.SEPTEMBER , 30 ) // Returns a `LocalDate` object, represent a date-only value without a time-of-day and without a time zone.
) // Returns a `YearQuarter` object.
.plusQuarters( 1 ) // Perform date-math, resulting in a new `YearQuarter` object (per immutable objects pattern).
.atEndOfQuarter() // Determine the date of last day of this year-quarter.
.toString() // Generate text in standard ISO 8601 format.
2020-12-31
org.threeten.extra.YearQuarter
The ThreeTen-Extra library provides classes that extend the functionality of the java.time classes built into Java 8 and later. One of its classes is YearQuarter to represent a specific quarter in a specific year. The quarters are defined by calendar-year: Jan-Mar, Apr-June, July-Sept, Oct-Dec.
LocalDate localDate = LocalDate.of( 2020 , Month.SEPTEMBER , 30 ) ;
YearQuarter yearQuarter = YearQuarter.from( localDate ) ;
Move to the next quarter by adding one quarter to our current year-quarter.
The java.time and ThreeTen-Extra classes use immutable objects. So rather than alter ("mutate") the original object, when adding we produce a new object.
YearQuarter followingYearQuarter = yearQuarter.plusQuarters( 1 ) ;
Determine the last day of that quarter.
LocalDate lastDateOfFollowingYearQuarter = followingYearQuarter.atEndOfQuarter() ;
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.
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.
Here is my version (hopefully more readable) of finding the last day of next quarter for any date:
public LocalDate lastDayOfNextQuarter(LocalDate date) {
Month firstMonthOfCurrentQuarter = date.getMonth().firstMonthOfQuarter();
LocalDate lastMonthOfCurrentQuarter = date.with(firstMonthOfCurrentQuarter.plus(2));
LocalDate lastMonthOfNextQuarter = lastMonthOfCurrentQuarter.plusMonths(3);
return lastMonthOfNextQuarter.with(lastDayOfMonth());
}
And a corresponding test method:
#ParameterizedTest
#CsvSource({"2020-01-01,2020-06-30", "2020-02-01,2020-06-30", "2020-03-01,2020-06-30", "2020-04-10,2020-09-30",
"2020-05-10,2020-09-30", "2020-06-10,2020-09-30", "2020-07-20,2020-12-31", "2020-08-20,2020-12-31",
"2020-09-30,2020-12-31", "2020-10-30,2021-03-31", "2020-11-30,2021-03-31", "2020-12-31,2021-03-31"})
public void testLastDayOfNextQuarter(LocalDate input, LocalDate expected) {
LocalDate result = timeUtils.lastDayOfNextQuarter(input);
assertEquals(expected, result);
}
You can manipulate quarter easily with TemporalAdjusters. See below:
LocalDate localDate = LocalDate.now();
LocalDate firstDayOfQuarter = localDate.with(IsoFields.DAY_OF_QUARTER, 1);
System.out.println(firstDayOfQuarter);
LocalDate lastDayOfQuarter = firstDayOfQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfQuarter);
LocalDate firstDateOfNextQuarter = lastDayOfQuarter.plusDays(1);
LocalDate lastDayOfNextQuarter = firstDateOfNextQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfNextQuarter);
Output:
2020-01-01
2020-03-31
2020-06-30
You can use a Calendar instance to get the last day of the month.
String str = "30-12-20";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yy");
Date date = format.parse(str);
Date newDate = DateUtils.addMonths(date, 3);
Calendar cal = new GregorianCalendar();
cal.setTime(newDate);
System.out.println(cal.getActualMaximum(Calendar.DAY_OF_MONTH));

Getting a Date from a GregorianCalendar

The GregorianCalendar is being inconsistent:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Results in
946681200000, 946681200000, 946684800000
This represents 2000-01-01 midnight in GMT+1, GMT+1 and UTC respectively. My timezone is +1 hour relative to UTC.
The problem here is that the getTimeInMillis is supposed to return the amount of milliseconds since 1970-01-01 in UTC. Only testCalThree is correct.
Another problem is that setTimeZone is seemingly not working depending on whether I called getTimeInMillis before.
My goal is to take a Calendar I receive as parameter from other code and get a UTC (java.util) Date for further use.
tl;dr
myGregCal.toZonedDateTime()
.toInstant()
…or…
java.util.Date.from(
myGregCal.toZonedDateTime()
.toInstant()
)
java.time
My goal is to take a Calendar I receive as parameter from other code and get a UTC (java.util) Date for further use.
The troublesome old date-time classes of Calendar and Date are now legacy, supplanted by the java.time classes. Fortunately you can convert to/from java.time by calling new methods on the old classes.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
For UTC value, extract an Instant. That class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = zdt.toInstant() ;
To generate a String representing that UTC value in a standard ISO 8601 format, call toString.
String output = instant.toString() ;
If you need other formats in generated strings, convert to the more flexible OffsetDateTime and use DateTimeFormatter. Search Stack Overflow for many examples.
Best to avoid the Date class. But if you must, convert. Like Instant, Date represents a point on the timeline in UTC. But Date is limited to milliseconds resolution. So you risk data loss, lopping off digits from the decimal fraction of a second beyond the 3 digits of milliseconds versus 9 digits of nanoseconds.
java.util.Date utilDate = Date.from( instant ) ;
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 java.time.
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 and 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 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….
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.
I think it's a bug in the Calendar implementation. time is cached, i.e. if you've calculated it once it is reused unless something changes.
But somehow setting time zone is not recognized as a relevant change.
You can force re-calculation of time in ms by changing or clearing some field explicitly. So this:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.clear(Calendar.ZONE_OFFSET);
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
Gives:
946681200000, 946684800000, 946684800000
As you would expect. The only thing I had to do is cal.clear(Calendar.ZONE_OFFSET) before setting time zone.
Anyway, I'd like to repeat the recommendation from comments. If you value your sanity, switch to JodaTime or Java8 date/time.
Upon thinking further on it, the code may work as intended. setTimeZone may just function differently depending on whether a getter has been called upon the Calendar or not.
In the first case, it changes the timezone, but because the time has already been gotten and therefore initialized, the UTC time is unchanged.
In the second case, it indicates that the initializing date of 2001-1-1 we passed in the constructor was a UTC time and should be parsed as UTC rather than the local timezone.
If so, then the results make sense.

[Android]Get hour from string

Hello I'm trying to convert a string in the format "17:50" to a date in android but when I try to run this code I get the correct hour from the string but the full date is from 1970. I need this date to schedule some local notifications on a given time of the day or in the next day.
String dtStart = "17:50";
SimpleDateFormat format = new SimpleDateFormat("H:mm");
try {
Calendar cal = Calendar.getInstance();
Date date = format.parse(dtStart);
cal.setTime(date);
System.out.println(cal.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
Thu Jan 01 17:50:00 BRT 1970
It's not an error, your code works well. Just if you want to get current date, you have to add the difference between current day and 1st of January 1970.
Your parsed date gives you 17:30 hours, which means 17 * 60 * 60 * 1000 ms + 30 * 60 + 1000 ms.
This way you can find current day: https://stackoverflow.com/a/1908419/4142087
What Anton suggested was correct, and the current day / next day logic is your custom implementation. You have to check current time and if it past that time, jump to setting up the alarm the next day.
java.time
You need a time-of-day class to represent your intended meaning. The legacy date-time classes from the earliest versions of Java lack such a class. The java.sql.Time class pretends to do this, but actually contains a date as well due to poor design decisions.
LocalTime
You want the LocalTime class for a time-of-day value without a date and without a time zone.
It uses a generic 24-hour single-day clock. Adding/subtracting spans of time wraps around the clock since it lacks any concept of dates.
Define a formatting pattern to match your input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "H:mm" ) ; // Uppercase `H` means 24-hour clock, lowercase `h` means 12-hour clock.
Parse input string.
String input = "7:50" ;
LocalTime lt = LocalTime.parse( input , f ) ;
Generate a string in standard ISO 8601 format.
String output = lt.toString() ;
07:50
Perhaps your business logic requires assigning the time-of-day to a date. To determine a moment, a point on the timeline, you must also specify a time zone.
LocalDate ld = LocalDate.of( 2018 , Month.MARCH , 27 ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
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.

What is the correct way to create a timestamp in Java?

Given a year, month, day, hour, minute and second, what is the correct way to create a Java UTC (GMT) timestamp?
Options I've considered, but remain to be convinced by:
1 - use deprecated Date constructors
java.util.Date date = new java.util.Date(year - 1900, month, dayOfMonth, hour, minute, second);
long timestamp = date.getTime();
2 - use a calendar with TimeZone set to GMT
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, second);
c.set(Calendar.MILLISECOND, 0);
long timestamp = c.getTimeInMillis();
One of my issues with this is that I'm finding it very hard to test without getting mixed up in more TimeZone issues.
Is there a definitive right way to do this with the standard APIs?
Update: would like to get an answer to this using standard JavaSE. I know Joda-Time is wonderful, but it's not an option in this case.
tl;dr
OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC )
java.time
The modern approach uses the java.time classes.
Unlike the troublesome legacy date-time classes, the java.time classes use sane numbering:
2018 means the year 2018. (No crazy math with 1900.)
1-12 for months January-December. (Not silly 0-11.)
1-7 for Monday-Sunday per ISO 8601 standard definition of week. (No varying by locale.)
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
You a one-liner if you wish, if parsing a string.
Instant instant = Instant.parse( "2018-01-23T12:34:56Z" ) ;
While Instant is a basic building-block class for java.time, the OffsetDateTime class is more flexible. The offset-from-UTC of UTC itself is defined as a constant for your convenience.
OffsetDateTime odt = OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC ) ;
Personally, I prefer using pieces.
In place of a mere integer for month, you may specify a Month enum object.
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ; // Date-only, without time-of-day.
LocalTime lt = LocalTime.of( 12 , 34 , 56 ) ; // Time-of-day, without date.
ZoneOffset offset = ZoneOffset.UTC ;
OffsetDateTime odt = OffsetDateTime.of( ld , lt , offset ) ;
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor 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, 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.
No, there isn't (unless you can use Joda-Time), the correct way is to use Calendar and the calendar API is ugly, nothing anyone can do about it at the moment.
Standard Java APIs for dates are pretty inconvenient. Consider using Joda-Time:
long timestamp = new LocalDateTime(year, month, day, hour, minute, second)
.getLocalMillis();
I think this would work pretty good
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
Date date = sdf.parse("2011-12-21 12:00:00+0000");
You would have to build the date string on your own but it's short and should work fine. And create the SimpleDateFormat to your liking, the important part is the Z that corresponds to
"+0000".
Here is another alternative way on the same lines
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2011-12-21 12:00:00");
It's with an explicit time zone and the Z is removed.

How to subtract X days from a date using Java calendar?

Anyone know a simple way using Java calendar to subtract X days from a date?
I have not been able to find any function which allows me to directly subtract X days from a date in Java. Can someone point me to the right direction?
Taken from the docs here:
Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules. For example, to subtract 5 days from the current time of the calendar, you can achieve it by calling:
Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).
You could use the add method and pass it a negative number. However, you could also write a simpler method that doesn't use the Calendar class such as the following
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
This gets the timestamp value of the date (milliseconds since the epoch) and adds the proper number of milliseconds. You could pass a negative integer for the days parameter to do subtraction. This would be simpler than the "proper" calendar solution:
public static void addDays(Date d, int days)
{
Calendar c = Calendar.getInstance();
c.setTime(d);
c.add(Calendar.DATE, days);
d.setTime( c.getTime().getTime() );
}
Note that both of these solutions change the Date object passed as a parameter rather than returning a completely new Date. Either function could be easily changed to do it the other way if desired.
Anson's answer will work fine for the simple case, but if you're going to do any more complex date calculations I'd recommend checking out Joda Time. It will make your life much easier.
FYI in Joda Time you could do
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
tl;dr
LocalDate.now().minusDays( 10 )
Better to specify time zone.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Details
The old date-time classes bundled with early versions of Java, such as java.util.Date/.Calendar, have proven to be troublesome, confusing, and flawed. Avoid them.
java.time
Java 8 and later supplants those old classes with the new java.time framework. See Tutorial. Defined by JSR 310, inspired by Joda-Time, and extended by theThreeTen-Extra project. The ThreeTen-Backport project back-ports the classes to Java 6 & 7; the ThreeTenABP project to Android.
The Question is vague, not clear if it asks for a date-only or a date-time.
LocalDate
For a date-only, without time-of-day, use the LocalDate class. Note that a time zone in crucial in determining a date such as "today".
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
If you meant a date-time, then use the Instant class to get a moment on the timeline in UTC. From there, adjust to a time zone to get a ZonedDateTime object.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
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, 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.
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
See java.util.Calendar#add(int,int)
Instead of writing my own addDays as suggested by Eli, I would prefer to use DateUtils from Apache. It is handy especially when you have to use it multiple places in your project.
The API says:
addDays(Date date, int amount)
Adds a number of days to a date returning a new object.
Note that it returns a new Date object and does not make changes to the previous one itself.
I faced the same challenge where I needed to go back by 1 day (should be able to roll back by one even if previous day falls into previous year or months).
I did following, basically subtracted by 24 hours for 1 day.
someDateInGregorianCalendar.add(Calendar.HOUR, -24);
Alternatively, I could also do
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.YEAR, 2021);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DATE, 1);
System.out.println("Original: " + cal.getTime());
cal.add(Calendar.DATE, -1);
System.out.println("After adding DATE: " + cal.getTime());
OUTPUT:
Original: Fri Jan 01 15:08:33 CET 2021
After adding DATE: Thu Dec 31 15:08:33 CET 2020
It can be done easily by the following
Calendar calendar = Calendar.getInstance();
// from current time
long curTimeInMills = new Date().getTime();
long timeInMills = curTimeInMills - 5 * (24*60*60*1000); // `enter code here`subtract like 5 days
calendar.setTimeInMillis(timeInMills);
System.out.println(calendar.getTime());
// from specific time like (08 05 2015)
calendar.set(Calendar.DAY_OF_MONTH, 8);
calendar.set(Calendar.MONTH, (5-1));
calendar.set(Calendar.YEAR, 2015);
timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000);
calendar.setTimeInMillis(timeInMills);
System.out.println(calendar.getTime());
I believe a clean and nice way to perform subtraction or addition of any time unit (months, days, hours, minutes, seconds, ...) can be achieved using the java.time.Instant class.
Example for subtracting 5 days from the current time and getting the result as Date:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Another example for subtracting 1 hour and adding 15 minutes:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
If you need more accuracy, Instance measures up to nanoseconds. Methods manipulating nanosecond part:
minusNano()
plusNano()
getNano()
Also, keep in mind, that Date is not as accurate as Instant. My advice is to stay within the Instant class, when possible.
Someone recommended Joda Time so - I have been using this CalendarDate class http://calendardate.sourceforge.net
It's a somewhat competing project to Joda Time, but much more basic at only 2 classes. It's very handy and worked great for what I needed since I didn't want to use a package bigger than my project. Unlike the Java counterparts, its smallest unit is the day so it is really a date (not having it down to milliseconds or something). Once you create the date, all you do to subtract is something like myDay.addDays(-5) to go back 5 days. You can use it to find the day of the week and things like that.
Another example:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
And:
//print 4 previous days of the week and today
String dayLabel = "";
CalendarDate today = new CalendarDate(TimeZone.getDefault());
CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon"
CalendarDate currDay = today.addDays(-4);
while(!currDay.isAfter(today)) {
dayLabel = cdf.format(currDay);
if (currDay.equals(today))
dayLabel = "Today";//print "Today" instead of the weekday name
System.out.println(dayLabel);
currDay = currDay.addDays(1);//go to next day
}
Eli Courtwright second solution is wrong, it should be:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());

Categories

Resources