Subtract date to get yesterday date [duplicate] - java

This question already has answers here:
How to check if a date Object equals yesterday?
(9 answers)
Closed 8 years ago.
I have these codes to get the date today in my server
DefaultTableModel dnow = MyDB.DataTable("SELECT date_format(now(),'%m-%d-%Y')");
and these code for the formatting for the date.
SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy");
now how can I get the date of yesterday?
should I just minus it with one?

An alternative approach is to do the math in SQL. The statement may vary depending on what database platform you're using.
DefaultTableModel dnow =
MyDB.DataTable("SELECT date_format(now() - INTERVAL 1 DAY,'%m-%d-%Y')");

No, build a Date (or better yet use joda's DateTime object) and then do your arithmetic. I will give you two solutions, one with Joda and the other without, starting with without:
Date d = format.parse(dnow.getDataVector().get(dnow.getTable().getSelectedRow()));
d.add(Calendar.DATE, -1);
Now, using joda:
DateTime d = new DateTime(format.parse(dnow.getDataVector().get(dnow.getTable().getSelectedRow()))).minusDays(1);

This should work perfect for you,
Calendar cal = Calendar.getInstance()
cal.add(Calendar.DATE, -1);
System.out.println("Yesterday's date = "+ cal.getTime());
This will simply subtract 1 day from the current calendar date, providing you yesterdays date

If you store your timestamps internally as POSIX times (milliseconds since MN Jan 1, 1970) then you can add or subtract a day to any time stamp as easily as:
Date today = new Date(); // today
Date tomorrow = new Date(today.getTime() + (24 * 60 * 60 * 1000)); // tomorrow
The huge bonus to POSIX time is that it is always in UTC. UTC is a global, "fixed" point of reference. Then if you need to need to have this date displayed for the user in any time zone, in any daylight savings zone, for any place that is accounted for in the Olson Time Zone database, you can simply create a Calendar:
GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("America/Chicago"));
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setCalendar(gc);
sdf.applyPattern("MM-dd-yyyy");
// Now your formatter is set with the pattern and a time zone-aware Calendar.
// The world is at your command
String myOutput = sdf.format(tomorrow);
I highly recommend dealing with timestamps internally in your data model in some form of UTC representation. Doing date arithmetic with POSIX time (or Julian Day Numbers, or Modified Julian Day Numbers) is easy peasy, and the Java date/time API has enough capability to deal with most local time conversions without much fuss from you.

Related

Firestore - Creating a query where results are within last 7 days [duplicate]

I have a report created in Jasper Reports which ONLY recognizes java.util.Date's (not Calendar or Gregorian, etc).
Is there a way to create a date 7 days prior to the current date?
Ideally, it would look something like this:
new Date(New Date() - 7)
UPDATE: I can't emphasize this enough: JasperReports DOES NOT RECOGNIZE Java Calendar objects.
From exactly now:
long DAY_IN_MS = 1000 * 60 * 60 * 24;
new Date(System.currentTimeMillis() - (7 * DAY_IN_MS))
From arbitrary Date date:
new Date(date.getTime() - (7 * DAY_IN_MS))
Edit: As pointed out in the other answers, does not account for daylight savings time, if that's a factor.
Just to clarify that limitation I was talking about:
For people affected by daylight savings time, if by 7 days earlier, you mean that if right now is 12pm noon on 14 Mar 2010, you want the calculation of 7 days earlier to result in 12pm on 7 Mar 2010, then be careful.
This solution finds the date/time exactly 24 hours * 7 days= 168 hours earlier.
However, some people are surprised when this solution finds that, for example, (14 Mar 2010 1:00pm) - 7 * DAY_IN_MS may return a result in(7 Mar 2010 12:00pm) where the wall-clock time in your timezone isn't the same between the 2 date/times (1pm vs 12pm). This is due to daylight savings time starting or ending that night and the "wall-clock time" losing or gaining an hour.
If DST isn't a factor for you or if you really do want (168 hours) exactly (regardless of the shift in wall-clock time), then this solution works fine.
Otherwise, you may need to compensate for when your 7 days earlier doesn't really mean exactly 168 hours (due to DST starting or ending within that timeframe).
Use Calendar's facility to create new Date objects using getTime():
import java.util.GregorianCalendar;
import java.util.Date;
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysAgo = cal.getTime();
try
Date sevenDay = new Date(System.currentTimeMillis() - 7L * 24 * 3600 * 1000));
Another way is to use Calendar but I don't like using it myself.
Since no one has mentioned TimeUnit yet:
new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
Java 8 based solution:
new Date(
Instant.now().minus(7, ChronoUnit.DAYS)
.toEpochMilli()
)
Try this:
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
return c.getTime();
A determining "days" requires a time zone. A time zone defines when a "day" begins. A time zone includes rules for handling Daylight Saving Time and other anomalies. There is no magic to make time zones irrelevant. If you ignore the issue, the JVM's default time zone will be applied. This tends to lead to confusion and pain.
Avoid java.util.Date
The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. They are so bad that Sun/Oracle agreed to supplant them with the new java.time package in Java 8. Use either that or Joda-Time.
Joda-Time
Example code in Joda-Time 2.3.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Specify or else the JVM's default will apply.
DateTime dateTime = new DateTime( new java.util.Date(), timeZone ); // Simulate passing a Date.
DateTime weekAgo = dateTime.minusDays( 7 );
First Moment Of Day
Or, you may want to adjust the time-of-day to the first moment of the day so as to capture an entire day's worth of time. Call the method withTimeAtStartOfDay. Keep in mind this is usually 00:00:00 but not always.
Avoid the "midnight" methods and classes in Joda-Time. They are based on a faulty concept and are now deprecated.
DateTime dateTimeStart = new DateTime( new java.util.Date(), timeZone ).withTimeAtStartOfDay(); // Not necessarily the time "00:00:00".
DateTime weekAgo = dateTime.minusDays( 7 ).withTimeAtStartOfDay();
Convert To/From j.u.Date
As seen above, to convert from java.util.Date to Joda-Time merely pass the Date object to constructor of DateTime. Understand that a j.u.Date has no time zone, a DateTime does. So assign the desired/appropriate time zone for deciding what "days" are and when they start.
To go the other way, DateTime to j.u.Date, simply call the toDate method.
java.util.Date date = dateTime.toDate();
I'm not sure when they added these, but JasperReports has their own set of "functions" that can manipulate dates. Here is an example that I haven't tested thoroughly:
DATE(YEAR(TODAY()), MONTH(TODAY()), DAY(TODAY()) - 7)
That builds a java.util.Date with the date set to 7 days from today. If you want to use a different "anchor" date, just replace TODAY() with whatever date you want to use.
You can try this,
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
System.out.println(new java.sql.Date(c.getTimeInMillis()));
Due to the heated discussion:
The question may not have a proper answer w/o a designated timezone.
below it is some code to work w/ the default (and hence deprecated) timezone that takes into account the default timezone daylight saving.
Date date= new Date();
date.setDate(date.getDate()-7);//date works as calendar w/ negatives
While the solution does work, it is exactly as bogus as in terms of assuming the timezone.
new Date(System.currentTimeMillis() - 10080*60000);//a week has 10080 minutes
Please, don't vote for the answer.
I'm doing it this way :
Date oneWeekAgo = DateUtils.addDays(DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH), -7);

error output converting date format from YYYYMMDD to dd-mm-yyyy

I have a problem on the java conversion of the dates.
I have input a String, YYYYMMDD, that converts to long and by executing the code the output is wrong
try {
//Current date to dd-mm-yyyy
Date currentDate = new Date(20161205); //or
DateFormat df = new SimpleDateFormat("dd-mm-yyyy");
String strCurrentDate = df.format(currentDate);
System.out.println("Date is " + strCurrentDate);
} catch (Exception e) {
System.out.println("Exception :" + e);
}
The output is: 01-49-1970
why?? How can I solve the problem
Solution:
Date currentDate = new Date(116,11,05);
Explanation:
You put single number as an argument of constructor of Date. If you take a look at list of available constructors of this class in Java API documentation here, you'll notice that the one taking long as argument will be chosen. As documentation states:
Date​(long date) - Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
Instead of that, if you really need to use java.util.date package (java.time is considered as the right choice nowadays), consider using another constructor: Date​(int year, int month, int date). In that case, you should pass the following numbers as parameters:
Date currentDate = new Date(116,11,05);
This is because:
year - the year minus 1900.
month - the month between 0-11.
date - the day of the month between 1-31.
By the way, consider using java.time package instead of java.util as java.util.Date is now deprecated.
you are doing it in the wrong way see
if you want to change date from this formate yyyyMMdd to this formateyyyy-MM-dd
you have to to change your code a little bit
try {
//Current date to dd-mm-yyyy
DateFormat fromFormate = new SimpleDateFormat("yyyyMMdd");
DateFormat toFormate = new SimpleDateFormat("yyyy-MM-dd");
String dateToFormate = "20161205"; //or
Date d=fromFormate.parse(dateToFormate);
System.out.println("Date is " + toFormat.formate(d));
} catch (Exception e) {
System.out.println("Exception :" + e);
}
tl;dr
LocalDate.parse(
"20161205",
DateTimeFormatter.BASIC_ISO_DATE
).format(
DateTimeFormatter.ofPattern("dd-MM-uuuu")
)
05-12-2016
Why 01-49-1970?
I cannot reproduce your exact output so can explain most of it, not all. Probably you’ve confused a couple of your test examples and didn’t get 01-49-1970 from new Date(20161205). On my computer I got Date is 01-36-1970. It’s bad enough.
As others have pointed out, new Date(20161205) gives you a point in time a little more than 20 000 seconds after the epoch of January 1, 1970 00:00 UTC. In UTC the time is then 5:36:01.205 (AM) on January 1. The time in your time zone probably differs. There are time zones where the date is still December 31, 1969.
But this doesn’t seem to explain how you seem to get an output in the 49th month of 1970, or I in the 36th month. This is because you used lowercase mm in your format pattern string. mm is for minute of hour. Uppercase MM is for month. So the 36 I got matches the minutes in the 5:36:01. There are time zones where the minutes are not the same; but I couldn’t find a time zone where the minute of hour is 49 at this time, so your exact reported output I cannot explain.
How can I solve the problem?
As others have said too, use java.time, the modern Java date and time API. It is so much nicer to work with.
LocalDate currentDate = LocalDate.of(2016, Month.DECEMBER, 5);
Or from a string:
LocalDate currentDate
= LocalDate.parse("20161205", DateTimeFormatter.BASIC_ISO_DATE);
Format to your desired output:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu");
String strCurrentDate = currentDate.format(dtf);
System.out.println("Date is " + strCurrentDate);
This prints
Date is 05-12-2016
As a bonus java.time will let you know through an exception if you happen to use mm instead of MM in the format pattern string above.
Link: Oracle Tutorial: Date Time explaining how to use java.time.
Like #oceano22 said, there are newer/better date/time packages available. That said, the reason this is happening is because when you called new Date(20161205) the parameter that date constructor takes is NOT yyyyMMdd. According to the javadoc... "Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT."
So really you've created a date just 20 million milliseconds after the Unix epoch (Jan 1, 1970).
I've you're trying to get Dec 5, 2016 into a Date use df.parse("05-12-2016") with the SimpleDateFormat df you have defined.
You also likely want capital M's for month in your date format e.g. "dd-MM-yyyy" because lowercase m's are for minutes.

Storing java util date into mysql as a timestamp

I am using JPA and MySQl
In my domain object i have a date field as
#Temporal(TemporalType.TIMESTAMP)
private Date lastSeenDate;
From my UI the date goes as a String in format dd-mm-yyyy
I used
final DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
final Date date = format.parse(dateString);
but for String date
06-06-2013
the date stored in mysql is
0011-12-04 00:00:00.0
How do I store it into mysql to match the mysql format
The class Date represents a specific instant in time, with millisecond
precision.
From: http://docs.oracle.com/javase/6/docs/api/java/util/Date.html
The date class always has a time component.
All dates in Java are essentially timestamps as they represent a single millisecond in time.
There's no way I can think of to deal only with dates but you might want to have a look at java.util.Calendar. If you can set the hours, minutes, seconds and milliseconds all to zero (or other defined time) you can then work with days, months and years more naturally. It's not a very good offering but it works well enough.
According to JavaDocs: java.util.Date allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
So, it works like a database Timestamp. It would always have a time component although it may be all zeroes that is representing a midnight. But, you could use the same SimpleDateFormat to print out the java.util.Date without its time component.
final DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
final Date utilDate = sdf.parse("2013-06-20");
System.out.println(sdf.format(utilDate)); // prints back 2013-06-20
Or, you may want to look into java.sql.Date which does not have a time component.
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

How to generate a Date from just Month and Year in Java?

I need to generate a new Date object for credit card expiration date, I only have a month and a year, how can I generate a Date based on those two? I need the easiest way possible. I was reading some other answers on here, but they all seem too sophisticated.
You could use java.util.Calendar:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();
java.time
Using java.time framework built into Java 8
import java.time.YearMonth;
int year = 2015;
int month = 12;
YearMonth.of(year,month); // 2015-12
from String
YearMonth.parse("2015-12"); // 2015-12
with custom DateTimeFormatter
import java.time.format.DateTimeFormatter;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM yyyy");
YearMonth.parse("12 2015", formatter); // 2015-12
Conversions
To convert YearMonth to more standard date representation which is LocalDate.
LocalDate startMonth = date.atDay(1); //2015-12-01
LocalDate endMonth = date.atEndOfMonth(); //2015-12-31
Possibly a non-answer since you asked for a java.util.Date, but it seems like a good opportunity to point out that most work with dates and times and calendars in Java should probably be done with the Joda-Time library, in which case
new LocalDate(year, month, 1)
comes to mind.
Joda-Time has a number of other nice things regarding days of the month. For example if you wanted to know the first day of the current month, you can write
LocalDate firstOfThisMonth = new LocalDate().withDayOfMonth(1);
In your comment you ask about passing a string to the java.util.Date constructor, for example:
new Date("2012-09-19")
This version of the constructor is deprecated, so don't use it. You should create a date formatter and call parse. This is good advice because you will probably have year and month as integer values, and will need to make a good string, properly padded and delimited and all that, which is incredibly hard to get right in all cases. For that reason use the date formatter which knows how to take care of all that stuff perfectly.
Other earlier answers showed how to do this.
Like
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM");
Date utilDate = formatter.parse(year + "/" + month);
Copied from Create a java.util.Date Object from a Year, Month, Day Forma
or maybe like
DateTime aDate = new DateTime(year, month, 1, 0, 0, 0);
Copied from What's the Right Way to Create a Date in Java?
The most common sense approach would be to use the Date("YYYY-MM-DD") constructor even though it is deprecated. This is the easiest way to create a date on the fly. Screw whoever decided to deprecate it. Long live Date("YYYY-MM-DD")!!!
Don’t use this answer. Use the answers by Przemek and Ray Toel. As Przemek says, prefer to use a YearMonth for representing year and month. As both say, if you must use a date, use LocalDate, it’s a date without time of day.
If you absolutely indispensably need an old-fashioned java.util.Date object for a legacy API that you cannot change, here’s one easy way to get one. It may not work as desired, it may not give you exactly the date that you need, it depends on your exact requirements.
YearMonth expiration = YearMonth.of(2021, 8); // or .of(2021, Month.AUGUST);
Date oldFashionedDateObject = Date.from(expiration
.atDay(1)
.atStartOfDay(ZoneId.systemDefault())
.toInstant());
System.out.println(oldFashionedDateObject);
On my computer this prints
Sun Aug 01 00:00:00 CEST 2021
What we got is the first of the month at midnight in my local time zone — more precisely, my JVM’s time zone setting. This is one good guess at what your legacy API expects, but it is also dangerous. The JVM’s time zone setting may be changed under our feet by other parts of the program or by other programs running in the same JVM. In other words, we cannot really be sure what we get.
The time zone issue gets even worse if the date is transmitted to a computer running a different time zone, like from client to server or vice versa, or to a database running its own time zone. There’s about 50 % risk that your Date will come through as a time in the previous month.
If you know the time zone required in the end, it will help to specify for example ZoneId.of("America/New_York") instead of the system default in the above snippet.
If your API is lenient and just needs some point within the correct month, you’ll be better off giving it the 2nd of the month UTC or the 3rd of the month in your own time zone. Here’s how to do the former:
Date oldFashionedDateObject = Date.from(expiration
.atDay(2)
.atStartOfDay(ZoneOffset.UTC)
.toInstant());

Data(timestamp).toLocaleString always return current date

In this code
long timestamp=1332782463298;
Date d=new Date(timestamp);
date=d.toLocaleString();
date is always current date. Where is my mistake?
I've also tried SimpleDateFormat, but it still returns current date:
date=new SimpleDateFormat("MM.dd.yyyy").format(d);
That timestamp is for March 26th 2012 (17:21:03.298 UTC, to be precise). Try a suitably different timestamp (e.g. 1332482563298L) and you'll get a different date...
Note that you shouldn't really be using toLocaleString anyway - SimpleDateFormat is the way to go (or Joda Time if possible). You might also want to consider which time zone you're interested in.
I'm sorry, but do you understand what long timestamp=1332782463298; is ? It's a UNIX time stamp in milliseconds since 1 January 1970, if you keep it same, date will contains same time all the time.
Use Calendar instead:
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1332782463298);
Date d = cal.getTime();
String current = SimpleDateFormat("MM.dd.yyyy").format(cal.getTime()).toString();

Categories