Generate a random date within some days back from today - java

I am trying to generate a random date in yyyy-mm-dd format for the following cases.
The random date should be within 90 days range from today.
The random date should be within 90 to 180 days from today.
The random date should be within 181 to 270 days from today.
I have written a short code snippet wherein I tried generating a random date but it does not give me the date in the range expected. That is between Sep 9 and Jan 14. It gives me the dates beyond Jan 14 also.
`public static void generateRandomDate() {
Date d1=new Date(2022, 9, 9);
Date d2=new Date(2023, 1, 14);
Date randomDate = new Date(ThreadLocalRandom.current()
.nextLong(d1.getTime(), d2.getTime()));
System.out.println(randomDate);
}`
Output: Wed Jan 17 23:41:37 IST 3923
I can use switch case to generate random dates according to the cases I want. But I am not able to get the desired date with the code I am trying and also I need to date to be in yyyy-mm-dd format. It will be really helpful if I will be able to pass the d1 and d2 in that format.

First of all, you should rather use a LocalDate instead of Date.
But going back to your question.
Current date can be obtained from:
LocalDate today = LocalDate.now();
And right now, you need to add appropriate number of days.
If your case, you can create method:
private LocalDate getRandomDateInFutureDaysRange(int start, int end) {
LocalDate today = LocalDate.now();
return today.plusDays(ThreadLocalRandom.current().nextLong(start, end));
}
For your use cases you can call it as follows:
getRandomDateInFutureDaysRange(0, 90)
getRandomDateInFutureDaysRange(90, 180)
getRandomDateInFutureDaysRange(181, 270)
To format the date you can use DateTimeFormatter as follows:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = yourDateToFormat.format(formatter);

Related

DateTimeFormatter and SimpleDateFormat produce different strings [duplicate]

This question already has answers here:
Why when year is less than 1884, it remove few milliseconds?
(2 answers)
Closed 3 years ago.
This is not a duplicate as some people think. It is about two standard Java classes for formatting dates that produce different strings for the same value of milliseconds since the epoch.
For values of milliseconds since the epoch that occur before some point in the year 1883, SimpleDateFormat and DateTimeFormatter will produce different results. For reasons I don't understand, DateTimeFormatter will produce strings that differ from what I expect by almost four minutes.
This is important because I am changing some code to use DateTimeFormatter instead of SimpleDateFormat. Our input is always milliseconds since the epoch, and I need the values to be the same after I change the code.
The previous code would create a Date from the milliseconds, then use SimpleDateFormat to format it.
The new code creates an Instant from the milliseconds, then a ZonedDateTime from the Instant, then a DateTimeFormatter to format it.
Here's a test I wrote using JUnit4 and Hamcrest. The test finds the milliseconds since the epoch for May 13, 15:41:25, for each year starting at 2019 and working backwards one year at a time.
For each year, it formats the milliseconds using SimpleDateFormat and DateTimeFormatter then compares the results.
#Test
public void testSimpleDateFormatVersusDateTimeFormatter() throws Exception {
String formatString = "EEE MMM dd HH:mm:ss zzz yyyy";
String timeZoneCode = "America/New_York";
ZoneId zoneId = ZoneId.of(timeZoneCode);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatString);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZoneCode));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatString);
for (int year = 0; year < 200; year++) {
long millis = getMillisSinceEpoch(2019 - year, 5, 13, 15, 41, 25, timeZoneCode);
System.out.printf("%s%n", new Date(millis));
// Format using a DateTimeFormatter;
Instant instant = Instant.ofEpochMilli(millis);
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, zoneId);
String dateTimeFormatterString = dateTimeFormatter.format(zonedDateTime);
// Format using a SimpleDateFormat
Date date = new Date(millis);
String simpleDateFormatString = simpleDateFormat.format(date);
System.out.println("dateTimeFormatterString = " + dateTimeFormatterString);
System.out.println("simpleDateFormatString = " + simpleDateFormatString);
System.out.println();
assertThat(simpleDateFormatString, equalTo(dateTimeFormatterString));
}
}
private long getMillisSinceEpoch(int year, int month, int dayOfMonth, int hours, int minutes, int seconds, String timeZoneId) {
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
Calendar calendar = Calendar.getInstance(timeZone);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
calendar.set(Calendar.SECOND, seconds);
return calendar.getTimeInMillis();
}
Running this you can see it passes for all years from 2019 back to 1884. So for any given year you see output like this:
Mon May 13 12:41:25 PST 1895
dateTimeFormatterString = Mon May 13 15:41:25 EST 1895
simpleDateFormatString = Mon May 13 15:41:25 EST 1895
But once it gets to 1883 it inexplicably fails:
Sun May 13 12:41:25 PST 1883
dateTimeFormatterString = Sun May 13 15:45:23 EST 1883
simpleDateFormatString = Sun May 13 15:41:25 EST 1883
java.lang.AssertionError:
Expected: "Sun May 13 15:45:23 EST 1883"
but: was "Sun May 13 15:41:25 EST 1883"```
The hours and seconds are obviously wrong.
By the way, if I change the time zone to "UTC", then the test passes.
According to https://www.timeanddate.com/time/change/usa/new-york?year=1883 (which was the first hit in a Google search for "1883 time adjustment"):
Nov 18, 1883 - Time Zone Change (LMT → EST)
When local standard time was about to reach
Sunday, November 18, 1883, 12:03:58 pm clocks were turned backward 0:03:58 hours to
Sunday, November 18, 1883, 12:00:00 noon local standard time instead.
3:58 matches the "almost four minutes" that you're seeing.
I haven't tested this, but I bet that if you iterate through months and days in addition to years, it occurs at that date.
See Also
Why when year is less than 1884, it remove few milliseconds?
Python pytz timezone conversion returns values that differ from timezone offset for different dates
Why is subtracting these two times (in 1927) giving a strange result? — a classic answered by Jon Skeet; not the same issue, but the same kind of issue
The Times Reports on "the Day of Two Noons"

How to convert two different strings to date format and finding their differences in JSP/JAVA

I have 2 strings
Str1: 2016-7-25.15.38. 32. 0 (This is what im getting from DB)
String2 : July 25, 2016 3:19 PM (This one I wrote a program to read from the email timestamp)
How to convert these 2 strings to date format and find their differnce in time.. Pls help.
Ive gone through so many pages in SO and google but not getting anything specific
How to convert these 2 strings to date format
Using Java 8, you'd parse them like this:
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime dt1 = ZonedDateTime.parse("2016-7-25.15.38. 32. 0",
DateTimeFormatter.ofPattern("uuuu-M-d.H.m. s. 0").withZone(zoneId));
ZonedDateTime dt2 = ZonedDateTime.parse("July 25, 2016 3:19 PM",
DateTimeFormatter.ofPattern("MMMM d, uuuu h:mm a").withZone(zoneId));
Using a non-standard indentation to align format string with value to be parsed, for easier comparison.
The code is using ZonedDateTime so Daylight Savings Time will be handled correctly.
and find their difference in time
Getting the difference in time is then easy enough, using until() or between():
long seconds = dt1.until(dt2, ChronoUnit.SECONDS);
long seconds = ChronoUnit.SECONDS.between(dt1, dt2);
They are the same. Use whichever you like best.
If you print the values above, you get (I'm in USA Eastern time zone):
2016-07-25T15:38:32-04:00[America/New_York]
2016-07-25T15:19-04:00[America/New_York]
-1172
I would simply use Oracle to figure out the difference. It's quite easy:
select to_date('2016-07-25.15.38.32', 'yyyy-mm-dd.hh24.mi.ss') - to_date('July 25, 2016 3:19 PM', 'Month dd, yyyy hh:mi PM')
from dual
1.Convert java.sql.timestamp into java.util.Date
Date startDate = new Date(startTimestamp.getTime());
Date endDate= new Date(endTimestamp.getTime());
2.You can find the time difference using TimeUnit enum as below.
Date startDate = // Set start date
Date endDate = // Set end date
long duration = endDate.getTime() - startDate.getTime();
long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
and so on..

Creating a new date in Java using ints

I am currently using a Date Picker, to display/select a date. I am just having trouble with the format. below is how the example constructed it.
new StringBuilder().append(month + 1)
.append("-").append(day).append("-").append(year)
.append(" ").toString();
I don't want this format so I tried the following but it keeps giving the incorrect year even if the values are correct so I am not sure what I am doing wrong.
SimpleDateFormat dateFormat = new SimpleDateFormat("d MMMM yyyy");
Date date = new Date(year,month,day);
dates.setText(dateFormat.format(date));
for example if the date was 6 November 2015(current date) and I change it to 6 December 2015 it will display 6 December 3915
The following values are being returned year = 2015 month = 11 day = 6
And this Creates 6 December 3915 I don't understand why the year is not displaying properly if I choose 2016 it would be 3916
This behaviour can be expected actually. This is what the documentation says about the Date constructor you are using (emphasis added by me):
public Date(int year, int month, int day)
Deprecated. instead use the constructor Date(long date)
Constructs a Date object initialized with the given year, month, and day.
The result is undefined if a given argument is out of bounds.
Parameters:
year - the year minus 1900; must be 0 to 8099. (Note that 8099 is 9999 minus 1900.)
month - 0 to 11
day - 1 to 31
So you get 3915 because 2015 + 1900 = 3915
I recommend you don't use this constructor. First of all it is marked as deprecated. Most importantly, no person in his right mind would see an argument int year in a method and think "Of course I have to subtract 1900 from the value I pass"
The LocalDate introduced in Java 8 is recommended as a replacement. You would use it like this
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd MMMM yyyy");
LocalDate date = LocalDate.of(2015, Month.NOVEMBER, 6);
dates.setText(dateFormat.format(date));
the format you are using is wrong. try this instead:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM YYYY");

How to format date for use in a URL as a parameter

I am using an API to get a weather forecast up until a particular date in Java.
The requirement for passing a date as a URL parameter is that it must be in "YYYY-MM-DD'T'HH:MM:SS" format. I get input in this format from the user, then get the current system date, and then loop until the desired date. The problem lies in converting the input date string into the date format, incrementing it by one day, and then converting it back to the string format for URL parameter.
I am using the following code to do this but it is giving me incorrect results:
formatter = new SimpleDateFormat("YYYY-MM-DD'T'HH:MM:SS");
Date date1 = formatter.parse(inputtime);
System.out.println(date1);
Calendar c1 = Calendar.getInstance();
c1.setTime(date1);
c1.add(Calendar.DAY_OF_MONTH, 1); // number of days to add
inputtime = formatter.format(c1.getTime()); // dt is now the new date
System.out.println(c1.getTime());
System.out.println(inputtime);
inputtime is the input by the user. If I give "2014-04-12T00:00:00" as inputtime, date1 is then "Sun Dec 29 00:00:00 PKT 2013", c1.getTime() returns "Mon Dec 30 00:00:00 PKT 2013" and inputtime becomes then "2014-12-364T00:12:00" according to the above code block.
How can this logic error be corrected?
You should consider SimpleDateFormat date and time patterns: link
For example, something like this:
formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Have a try to change your date pattern from
new SimpleDateFormat("YYYY-MM-DD'T'HH:MM:SS");
to
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Letter Date or Time Component Presentation Examples
y Year Year 1996; 96
M Month in year Month July; Jul; 07
D Day in year Number 189
d Day in month Number 10
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them.
That format is defined by the ISO 8601 standard. The Joda-Time library follows that standard's formats as a default for both parsing and generating strings. So does the new java.time package in Java 8.
Your string omits a time zone offset. So, you need to know and specify the time zone intended by that string. Perhaps the time zone is UTC meaning a time zone offset of zero.
A day is not always 24 hours. If you meant 24 hours rather than 1 day, call the method plusHours( 24 ).
Here is example code in Joda-Time 2.3.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.UTC;
DateTime dateTime = new DateTime( input, timeZone );
DateTime tomorrow = dateTime.plusDays( 1 );
String outputWithOffset = tomorrow.toString();
String output = ISODateTimeFormat.dateHourMinuteSecond().print( tomorrow );

problems with java.util.Calendar and timeZones

I have following method which convert my custom DMY (date,month,year) object to Date.
public static Date serverCreateDateFromDMY(DMY pDMY, TimeZone pTimeZone)
{
Calendar vCalendar = Calendar.getInstance(pTimeZone);
vCalendar.set(Calendar.YEAR, pDMY.getYear());
// Below line is because DMY month counts are 1-indexed
// and Date month counts are 0-indexed
vCalendar.set(Calendar.MONTH, pDMY.getMonthOfYear() - 1);
vCalendar.set(Calendar.DAY_OF_MONTH, pDMY.getDayOfMonth());
System.out.println(vCalendar.getTime());
TimeUtilsServer.zeroCalendarHoursAndBelow(vCalendar);
System.out.println(vCalendar.getTime());
return vCalendar.getTime();
}
public static void zeroCalendarHoursAndBelow(Calendar pToZero)
{
pToZero.set(Calendar.HOUR_OF_DAY, 0);
pToZero.set(Calendar.MINUTE, 0);
pToZero.set(Calendar.SECOND, 0);
pToZero.set(Calendar.MILLISECOND, 0);
}
to serverCreateDateFromDMY() method, I am passing these arguments : DMY=20120424, and TimeZone is : America/New_York. Application is running locally in my timezone which is IST.
based in above inputs, following output is printed.
Tue Apr 24 14:43:07 IST 2012
Tue Apr 24 09:30:00 IST 2012
so as you see that in last output time is not zeroed out. any suggestions please?
#Marko, yes I come to know about DateFormat and I tried following example. but still date is printed with time and not zeroing out.
TimeZone tz = TimeZone.getTimeZone("America/New_York");
Calendar vCalendar = Calendar.getInstance(tz);
vCalendar.set(Calendar.YEAR, 2012);
vCalendar.set(Calendar.MONTH, 4 - 1);
vCalendar.set(Calendar.DAY_OF_MONTH, 24);
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(tz);
System.out.println(df.format(vCalendar.getTime()));
vCalendar.set(Calendar.HOUR_OF_DAY, vCalendar.getActualMinimum(Calendar.HOUR_OF_DAY));
vCalendar.set(Calendar.MINUTE, vCalendar.getActualMinimum(Calendar.MINUTE));
vCalendar.set(Calendar.SECOND, vCalendar.getActualMinimum(Calendar.SECOND));
vCalendar.set(Calendar.MILLISECOND, vCalendar.getActualMinimum(Calendar.MILLISECOND));
System.out.println(df.format(vCalendar.getTime()));
java Date / Time API have a bad design from the time of its creation. Maybe you should take a look at some library - for example this which hides JDK API deficiencies - http://joda-time.sourceforge.net/
Internally, Date and Calendar objects are stored in UTC. When you set the fields to 0, the Calendar is updated in UTC.
When you ask the Calendar for the time, it then converts the Date to your desired Timezone, hence the difference.
... and you are 9:30h ahead of NY time. You set the time to midnight NY time and read it out as time in your zone. Note that getTime returns a Date, which is not timezone-configurable. You'll need DateFormat if you want to specify the timezone for which you print the result.

Categories

Resources