How to create an iterater over days in JodaTime - java

I need to populate JComboBox with days as follows:
April 1, 2014
April 2, 2014
...
April 10,2014
I am using JodaTime to define dates. However, I don't know how to create an iterater over days in JodaTime.
JComboBox<String> days = new JComboBox<String>();
DateTime startD = new DateTime(2014, 4, 1, 0, 0, 0);
for (int i=0; i<10; i++)
{
// DateTime nextD = ...
days.addItem(startD.toString(DateTimeFormat.forPattern("yyyyMMdd")));
}

DateTime currentDate = startD.plusDays(i);
You should have found that easily by reading the javadoc.
Note that unless you really want the items to represent a precise instant (i.e. the first april at midnight in your timezone), you should probably use a LocalDate instead of a DateTime.

Related

Find Latest timestamp from DateTime class

I have a list of DateTime objects and my task is to compare them and find the latest timestamp. The DateTime class is used from Joda API. I have been stuck on this part for a little while now. I would appreciate the help.
Collections.max()
DateTimeZone dtz = DateTimeZone.forID("Indian/Comoro");
List<DateTime> dateTimeObjects = Arrays.asList(
new DateTime(2021, 2, 13, 21, 0, dtz),
new DateTime(2021, 2, 13, 22, 0, dtz),
new DateTime(2021, 2, 13, 23, 0, dtz));
DateTime latestDateTime = Collections.max(dateTimeObjects);
System.out.println(latestDateTime);
Output:
2021-02-13T23:00:00.000+03:00
Collections.max() throws a NoSuchElementException if the list is empty. It throws a NullPointerException if the list contains a null (except perhaps if the null is the sole element, then it may get returned).
When comparing DateTime objects from different time zones Joda-Time first compares the instants, the points in time, so also in this case you are getting the latest. For example:
List<DateTime> dateTimeObjects = Arrays.asList(
new DateTime(2021, 2, 13, 21, 0, DateTimeZone.forID("Asia/Istanbul")),
new DateTime(2021, 2, 13, 22, 0, DateTimeZone.forID("Atlantic/Madeira")),
new DateTime(2021, 2, 13, 23, 0, DateTimeZone.forID("Antarctica/Macquarie")));
DateTime latestDateTime = Collections.max(dateTimeObjects);
System.out.println(latestDateTime);
Output:
2021-02-13T22:00:00.000Z
We got the time 22:00 for Madeira. You may wonder that the time 23:00 for Macquarie would seem later, but Macquarie is at UTC offset +11:00, so that time is in fact 10 hours earlier. DateTime objects are Comparable and compare by instant, not by clock hour. So we have got the latest point in time. We always will, also when several time zones are mixed.
Documentation link: Collections.max()

Is it possible to turn java.util.Date() to int?

I am developing an application where I have a JFormattedTextField with the current date in yyyy/mm/dd format and I want to move to int only these values. But the problem and what the eu am doing is returning more values
JFormattedTextField textId = new JFormattedTextField(new SimpleDateFormat("yyyy/MM/dd"));
textId.setValue(new java.util.Date());
textId.setBounds(20, 310, 100, 25);
Date data = (Date)textId.getValue();
long dataFinal = data.getTime();
How can I make the value of the Int only YYYY/MM/DD?
With long, the variable dataFinal at the moment gives 1603883824076 is this the current time in nanoseconds?
Two suggestions:
Use java.time, the modern Java date and time API, for your date work.
If you need an int, use a count of days since the epoch day of January 1, 1970.
The two suggestions go nicely hand in hand since java.time offers a toEpochDay method for the conversion:
Format localDateFormat = DateTimeFormatter.ofPattern("uuuu/MM/dd")
.toFormat(LocalDate::from);
JFormattedTextField textId = new JFormattedTextField(localDateFormat);
textId.setValue(LocalDate.now(ZoneId.systemDefault()));
textId.setBounds(20, 310, 100, 25);
LocalDate data = (LocalDate) textId.getValue();
int dataFinal = Math.toIntExact(data.toEpochDay());
Today — October 29, 2020 — will give you 18564.
… with long the variable datefinal at the moment gives 1603883824076
is this the current time in nanoseconds? …
They are milliseconds since the epoch of January 1, 1970, 00:00 UTC. And as you have probably noticed, they don’t fit into an int.
Links
Oracle tutorial: Date Time explaining how to use java.time.
My answer to the question how to make a jtextfield having a fixed date format? giving more detail on using LocalDate with JFormattedTextField.
Do you mean something like the following?
JFormattedTextField textId = new JFormattedTextField(new SimpleDateFormat("yyyy/MM/dd"));
textId.setValue(new java.util.Date());
textId.setBounds(20, 310, 100, 25);
String str = textId.getText().replaceAll("/", "");
int integer = Integer.parseInt(str);
The value of integer is 20201028 (because today's date is 2020/10/28, i.e. 28th October 2020)

How to create calender event using java date and time?

I want to create time events in Java.
For example: between March 1st to March 31st I want to create some events with start and end dates like:
Event1: March 3 to March 5
Event2: March 6 to March 10
Event2: March 13 to March 25
and so on.
These events should not overlap and an event should not contain March 1st and March 31st.
How I can do it using Java date and Time or Joda-Time?
I have an only basic idea that create a class with four variables as follows:
monthStart
monthEnd
eventStart
eventEnd
One alternative is to use the Time4J API, and create a DateInterval using PlainDate as start and end dates:
// March 1st and 31st
PlainDate start = PlainDate.of(2018, 3, 1);
PlainDate end = PlainDate.of(2018, 3, 31);
DateInterval interval = DateInterval.between(start, end);
With this, you can check if an event is inside this interval:
// Event1: March 3 to March 5
PlainDate eventStart = PlainDate.of(2018, 3, 3);
PlainDate eventEnd = PlainDate.of(2018, 3, 5);
DateInterval event1 = DateInterval.between(eventStart, eventEnd);
if (interval.encloses(event1)) {
// event1 is inside interval
}
You can also check if 2 events overlap:
// Event2: March 3 to March 5
eventStart = PlainDate.of(2018, 3, 6);
eventEnd = PlainDate.of(2018, 3, 10);
DateInterval event2 = DateInterval.between(eventStart, eventEnd);
if (event1.overlaps(event2)) {
// events 1 and 2 overlap
}
Your algorithm would be: create the full interval (such as from March 1st to March 31st) and create your events intervals, and then use the methods above (encloses and overlaps) accordingly.
Plain Java
With just Java's API, assuming you have Java 8, it's similar. The only difference is that Java doesn't have an Interval class and you have to compare the dates manually:
// March 1st and 31st
LocalDate start = LocalDate.of(2018, 3, 1);
LocalDate end = LocalDate.of(2018, 3, 31);
// Event1: March 3 to March 5
LocalDate eventStart = LocalDate.of(2018, 3, 3);
LocalDate eventEnd = LocalDate.of(2018, 3, 5);
// check if event1 is inside start and end dates
if (start.isBefore(eventStart) && eventEnd.isBefore(end)) {
// event is inside March 1st and 31st
}
LocalDate has the methods isBefore and isAfter to check if another date is before or after the date, and it also has the equals method to know if 2 dates are the same. The logic to know if 2 events overlap can be achieved by only using those methods as well, and "it's left as an exercise to the reader" :-)
If you have Java 7 or below, you can use the threeten backport, which has the LocalDate class as well.
Threeten Extra
In this API, there's an Interval class, but it works only with Instant, not with LocalDate.
You can make some workaround on this and assume that your dates are in UTC, and then use the Interval. I created an auxiliary method to do such conversion:
public Instant toInstant(LocalDate date) {
// convert to midnight in UTC
return date.atStartOfDay(ZoneOffset.UTC).toInstant();
}
And then use this to create the intervals:
// March 1st and 31st
Instant start = toInstant(LocalDate.of(2018, 3, 1));
Instant end = toInstant(LocalDate.of(2018, 3, 31));
Interval interval = Interval.of(start, end);
// Event1: March 3 to March 5
Instant eventStart = toInstant(LocalDate.of(2018, 3, 3));
Instant eventEnd = toInstant(LocalDate.of(2018, 3, 5));
Interval event1 = Interval.of(eventStart, eventEnd);
if (interval.encloses(event1)) {
// event1 is inside interval
}
// Event2: March 3 to March 5
eventStart = toInstant(LocalDate.of(2018, 3, 6));
eventEnd = toInstant(LocalDate.of(2018, 3, 10));
Interval event2 = Interval.of(eventStart, eventEnd);
if (event1.overlaps(event2)) {
// events 1 and 2 overlap
}
This is a workaround because it artificially sets the dates to midnight in UTC. As we only care about the day, month and year, though, this should do the trick (or you can also download the threeten extra's code and create another Interval class that works with LocalDate, and base your code on the original).
Joda-Time
Joda-Time is a discontinued project and the team is advising the migration to java.time API. Check in Joda-Time's website, there's a warning there saying:
Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310)
If you use Java 6 or 7, I recommend the threeten backport. For Java >= 8, use java.time with threeten extra or time4j. Only if you still use Java 5, then the best alternative is to use Joda-Time (actually, the ideal is to upgrade to a newer Java version, but anyway).
In Joda-Time, there are similar classes: LocalDate and Interval, and you need to convert the LocalDate to DateTime (assuming midnight in UTC) in order to work with intervals (similar to the conversion to Instant that we made above):
DateTime start = new LocalDate(2018, 3, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC);
DateTime end = new LocalDate(2018, 3, 31).toDateTimeAtStartOfDay(DateTimeZone.UTC);
Interval interval = new Interval(start, end);
DateTime eventStart = new LocalDate(2018, 3, 3).toDateTimeAtStartOfDay(DateTimeZone.UTC);
DateTime eventEnd = new LocalDate(2018, 3, 5).toDateTimeAtStartOfDay(DateTimeZone.UTC);
Interval event1 = new Interval(eventStart, eventEnd);
// contains accepts the same start or end dates, it needs additional checks to make sure dates are different
if (interval.contains(event1)
&& event1.getStart().isAfter(interval.getStart())
&& event1.getEnd().isBefore(interval.getEnd())) {
// interval contains event1, and start and end dates are not the same
}
eventStart = new LocalDate(2018, 3, 6).toDateTimeAtStartOfDay(DateTimeZone.UTC);
eventEnd = new LocalDate(2018, 3, 10).toDateTimeAtStartOfDay(DateTimeZone.UTC);
Interval event2 = new Interval(eventStart, eventEnd);
if (event1.overlaps(event2)) {
// events 1 and 2 overlap
}

Joda DateTime not giving the expected results

Given a DateTime object at 31-March-2011 and this code:
DateTime temp1 = new DateTime(2011, 3, 31, 12, 0, 0, 0);
DateTime temp2 = temp1.plusMonths(1);
DateTime temp3 = temp2.plusMonths(1);
after the execution
temp1 = 2011-03-31T12:00:00.000+02:00
temp2 = 2011-04-30T12:00:00.000+02:00
temp3 = 2011-05-30T12:00:00.000+02:00
temp3 is wrong here.
Is that above correct. Am I doing a mistake?
No, there's no mistake here. You're adding one month twice, which means the second time you'll get the result of adding a month to the possibly truncated result of adding the first month.
April only has 30 days, which is why you're getting April 30th for temp2 - and adding one month to April 30th gets you to May 30th.
If you want May 31st, use:
DateTime temp3 = temp1.plusMonths(2);
Basically, date and time arithmetic gives "odd" results if you try to think of it in terms of associativity etc.

How do you subtract Dates in Java? [duplicate]

This question already has answers here:
Calculating difference in dates in Java
(7 answers)
Closed 8 years ago.
My heart is bleeding internally after having to go so deep to subtract two dates to calculate the span in number of days:
GregorianCalendar c1 = new GregorianCalendar();
GregorianCalendar c2 = new GregorianCalendar();
c1.set(2000, 1, 1);
c2.set(2010,1, 1);
long span = c2.getTimeInMillis() - c1.getTimeInMillis();
GregorianCalendar c3 = new GregorianCalendar();
c3.setTimeInMillis(span);
long numberOfMSInADay = 1000*60*60*24;
System.out.println(c3.getTimeInMillis() / numberOfMSInADay); //3653
where it's only 2 lines of code in .NET, or any modern language you name.
Is this atrocious of java? Or is there a hidden method I should know?
Instead of using GregorianCalendar, is it okay to use Date class in util? If so, should I watch out for subtle things like the year 1970?
Thanks
It's indeed one of the biggest epic failures in the standard Java API. Have a bit of patience, then you'll get your solution in flavor of the new Date and Time API specified by JSR 310 / ThreeTen which is (most likely) going to be included in the upcoming Java 8.
Until then, you can get away with JodaTime.
DateTime dt1 = new DateTime(2000, 1, 1, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2010, 1, 1, 0, 0, 0, 0);
int days = Days.daysBetween(dt1, dt2).getDays();
Its creator, Stephen Colebourne, is by the way the guy behind JSR 310, so it'll look much similar.
You can use the following approach:
SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd");
long d1=formater.parse("2001-1-1").getTime();
long d2=formater.parse("2001-1-2").getTime();
System.out.println(Math.abs((d1-d2)/(1000*60*60*24)));
If you deal with dates it is a good idea to look at the joda time library for a more sane Date manipulation model.
http://joda-time.sourceforge.net/
Well you can remove the third calendar instance.
GregorianCalendar c1 = new GregorianCalendar();
GregorianCalendar c2 = new GregorianCalendar();
c1.set(2000, 1, 1);
c2.set(2010,1, 1);
c2.add(GregorianCalendar.MILLISECOND, -1 * c1.getTimeInMillis());
Here's the basic approach,
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date beginDate = dateFormat.parse("2013-11-29");
Date endDate = dateFormat.parse("2013-12-4");
Calendar beginCalendar = Calendar.getInstance();
beginCalendar.setTime(beginDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
There is simple way to implement it. We can use Calendar.add method with loop. The minus days between beginDate and endDate, and the implemented code as below,
int minusDays = 0;
while (true) {
minusDays++;
// Day increasing by 1
beginCalendar.add(Calendar.DAY_OF_MONTH, 1);
if (dateFormat.format(beginCalendar.getTime()).
equals(dateFormat.format(endCalendar).getTime())) {
break;
}
}
System.out.println("The subtraction between two days is " + (minusDays + 1));**

Categories