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)
Related
Initialize java.util.Calendar with May, 31 1900. Then add one year to it twenty times.
Here's code:
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
fun main(args : Array<String>) {
val f = SimpleDateFormat("yyyy.dd.MM")
val cal = Calendar.getInstance()
cal.set(1900, Calendar.MAY, 31)
for(i in 1..20) {
println(f.format(cal.time))
cal.add(Calendar.YEAR, 1)
}
}
The output is following:
1900.31.05
1901.31.05
1902.31.05
1903.31.05
1904.31.05
1905.31.05
1906.31.05
1907.31.05
1908.31.05
1909.31.05
1910.31.05
1911.31.05
1912.31.05
1913.31.05
1914.31.05
1915.31.05
1916.31.05
1917.31.05
1918.01.06
1919.01.06
Why I get June, 1 instead of May, 31 since 1918?
UPD: with time information
1917.31.05 23:38:50.611
1918.01.06 01:38:50.611
If this is DST invention, how do I prevent that?
You seem to be running your code in a timezone that changed its offset by two hours in 1917 or 1918. That is, the number of hours ahead or behind UTC changed. I've no idea why your timezone would have done that, but I'm sure there's a good historical reason for it.
If you're only interested in dates, without the Time component, use the java.time.LocalDate class, which effectively represents a day, month and year only. It's not subject to any daylight savings anomalies.
LocalDate today = LocalDate.now();
or
LocalDate moonLanding = LocalDate.of(1969, 7, 20);
I am assuming that you are in Europe/Moscow time zone. Turing85 in a comment correctly spotted the cause of the behaviour you observed: In 1918 summer time (DST) in your time zone began on May 31. The clock was moved forward from 22:00 to 24:00, that is, by two hours. Your Calendar object is aware of this and therefore refuses to give 23:38:50.611 on this date. Instead it picks the time 2 hours later, 1918.01.06 01:38:50.611. Now the month and day-of-month have changed to 1st of June.
Unfortunately this change is kept in the Calendar and carried on to the following year.
If this is DST invention, how do I prevent that?
Thomas Kläger in a comment gave the right solution: If you only need the dates, use LocalDate from java.time:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu.dd.MM");
LocalDate date = LocalDate.of(1900, Month.MAY, 31);
for (int i = 1; i <= 20; i++) {
System.out.println(date.format(dateFormatter));
date = date.plusYears(1);
}
Output (abbreviated):
1900.31.05
1901.31.05
…
1917.31.05
1918.31.05
1919.31.05
The “local” in LocalDate means “without timezone” in java.time jargon, so this is guaranteed to keep you free of surprises from time zone anomalies.
If you need a time, you may consider LocalDateTime, but since this is without time zone too, it will give you the non-existing time of 1918.31.05 23:38:50.611, so maybe not.
An alternative thing you may consider is adding the right number of years to your origin of 1900.31.05 23:38:50.611. Then at least you will only have surprises in years where you hit a non-existing time. I am using ZonedDateTime for this demonstration:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu.dd.MM HH:mm:ss.SSS");
ZonedDateTime originalDateTime = ZonedDateTime.of(1900, Month.MAY.getValue(), 31,
23, 30, 50, 611000000, ZoneId.of("Europe/Moscow"));
for (int i = 0; i < 25; i++) {
System.out.println(originalDateTime.plusYears(i).format(formatter));
}
Output:
1900.31.05 23:30:50.611
1901.31.05 23:30:50.611
…
1917.31.05 23:30:50.611
1918.01.06 01:30:50.611
1919.01.06 00:30:50.611
1920.31.05 23:30:50.611
…
1924.31.05 23:30:50.611
Again in 1919 summer time began on May 31. This time the clock was only advanced by 1 hour, from 23 to 24, so you get only 1 hour later than the imaginary time of 23:30:50.611.
I am recommending java.time for date and time work, not least when doing math on dates like you do. The Calendar class is considered long outmoded. java.time was designed acknowledging that Calendar and the other old classes were poorly designed. The modern ones are so much nicer to work with.
How could I be sure it was Moscow?
In no other time zone than Europe/Moscow is the time of 1918.31.05 23:38:50.611 nonexistent. I checked:
LocalDateTime dateTime = LocalDateTime.of(1918, Month.MAY, 31, 23, 38, 50, 611000000);
for (String zid : ZoneId.getAvailableZoneIds()) {
ZonedDateTime zdt = dateTime.atZone(ZoneId.of(zid));
LocalDateTime newDateTime = zdt.toLocalDateTime();
if (! newDateTime.equals(dateTime)) {
System.out.println(zid + ": -> " + zdt + " -> " + newDateTime);
}
}
Output:
Europe/Moscow: -> 1918-06-01T01:38:50.611+04:31:19[Europe/Moscow] -> 1918-06-01T01:38:50.611
W-SU: -> 1918-06-01T01:38:50.611+04:31:19[W-SU] -> 1918-06-01T01:38:50.611
“W-SU” is a deprecated name for the same time zone, it stands for Western Soviet Union.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Time Changes in Moscow Over the Years
List of tz database time zones showing W-SU as deprecated.
An old message on an IANA mailing list stating “But long ago … we based the name on some more-political entity than a city name. For example, we used "W-SU" for the western Soviet Union…”
I am trying to write a Java method to shift a Calendar, using a time offset in milliseconds.
But when I try to shift for one month (30 days) it does not work:
Calendar c = new GregorianCalendar(2012, 5, 23, 13, 23, 10);
long original = c.getTimeInMillis();
System.out.println("Original Date "+c.getTime());
long oneMonth = 30*24*60*60*1000; //one month in milliseconds
Calendar c_1Month = new GregorianCalendar();
c_1Month.setTimeInMillis(original+oneMonth);
System.out.println("After 1-month "+c_1Month.getTime());
The output is
Original Date Sat Jun 23 13:23:10 PDT 2012
After 1-month Sun Jun 03 20:20:22 PDT 2012
You can see that it does not shift it correctly to July 23rd.
I understand there is a specific method add(field, amount) in Calendar and I can change month using that, but I wanna have one single method in my client to shift time, with providing shift amount in milliseconds (the amount of shift changes based on my tests, and I do not want to have several methods for that).
You think the variable oneMonth is a long, but you assign it an integer value. But the result of 30*24*60*60*1000 doesn't fit into an integer and therefore overflows to a negative value.
If you change your code to long oneMonth = 30*24*60*60*1000L; it would work.
But despite of that "bug" in your code the comment of azurefrog is correct, this is not the recommended way to add one month, it would only be valid in case you like to add 30 days which is something different.
Try to use something like this instead:
c_1Month.add( Calendar.DAY_OF_MONTH, 30);
or
c_1Month.add( Calendar.MONTH, 1);
The Calendar class is aware and able to handle all corner cases very good. I would suggest you rely on this. It reduces possible bugs and makes code easier to read and understand.
With Java 8 the code to use would be:
LocalDateTime.now().plusMonths(1);
or
LocalDateTime.now().plusDays(30);
Add an "L" at the end of 30*24*60*60*1000
The way you are calculating, you are transforming the whole thing into an INTEGER.
Don't believe me :), try printing the value before adding the L after the 1000;
System.out.println(oneMonth);
Your final code should be:
Calendar c = new GregorianCalendar(2012, 5, 23, 13, 23, 10);
long original = c.getTimeInMillis();
System.out.println("Original Date "+c.getTime());
long oneMonth = 30*24*60*60*1000L; //one month in milliseconds
Calendar c_1Month = new GregorianCalendar();
c_1Month.setTimeInMillis(original+oneMonth);
System.out.println("After 1-month "+c_1Month.getTime());
I have a date and a number and want to check if this date and this number occurs in a list of other dates within:
+-20 date intervall with the same number
so for example 1, 1.1.2013 and 1,3.1.2013 should reuturn false.
I tried to implement the method something like that:
private List<EventDate> dayIntervall(List<EventDate> eventList) throws Exception {
List<EventDate> resultList = new ArrayList<EventDate>();
for (int i = 0; i < eventList.size(); i++) {
String string = eventList.get(i).getDate();
Date equalDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string);
for (int j = 0; j < eventList.size(); j++) {
String string1 = eventList.get(i).getDate();
Date otherDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string1);
if (check number of i with number of j && check Date) {
//do magic
}
}
}
return resultList;
}
The construction of the iteration method is not that hard. What is hard for me is the date intervall checking part. I tried it like that:
boolean isWithinRange(Date testDate, Date days) {
return !(testDate.before(days) || testDate.after(days));
}
However that does not work because days are not takes as days. Any suggestions on how to fix that?
I really appreciate your answer!
You question is difficult to follow. But given its title, perhaps this will help…
Span Of Time In Joda-Time
The Joda-Time library provides a trio of classes to represent a span of time: Interval, Period, and Duration.
Interval
An Interval object has specific endpoints that lie on the timeline of the Universe. A handy contains method tells if a DateTime object occurs within those endpoints. The beginning endpoint in inclusive while the last endpoint is exclusive.
Time Zones
Note that time zones are important, for handling Daylight Saving Time and other anomalies, and for handling start-of-day. Keep in mind that while a java.util.Date seems like it has a time zone but does not, a DateTime truly does know its own time zone.
Sample Code
Some code off the top of my head (untested)…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime dateTime = new DateTime( yourDateGoesHere, timeZone );
Interval interval = new Interval( dateTime.minusDays( 20 ), dateTime.plusDays( 20 ) );
boolean didEventOccurDuringInterval = interval.contains( someOtherDateTime );
Whole Days
If you want whole days, call the withTimeAtStartOfDay method to get first moment of the day. In this case, you probably need to add 21 rather than 20 days for the ending point. As I said above, the end point is exclusive. So if you want whole days, you need the first moment after the time period you care about. You need the moment after the stroke of midnight. If this does not make sense, see my answers to other questions here and here.
Note that Joda-Time includes some "midnight"-related methods and classes. Those are no longer recommended by the Joda team. The "withTimeAtStartOfDay" method takes their place.
DateTime start = dateTime.minusDays( 20 ).withTimeAtStartOfDay();
DateTime stop = dateTime.plusDays( 21 ).withTimeAtStartOfDay(); // 21, not 20, for whole days.
Interval interval = new Interval( start, stop );
You should avoid java.util.Date if at all possible. Using the backport of ThreeTen (the long awaited replacement date/time API coming in JDK8), you can get the number of days between two dates like so:
int daysBetween(LocalDate start, LocalDate end) {
return Math.abs(start.periodUntil(end).getDays());
}
Does that help?
You can get the number of dates in between the 2 dates and compare with your days parameter. Using Joda-Time API it is relatively an easy task: How do I calculate the difference between two dates?.
Code:
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
Date startDate = format.parse("1.1.2013");
Date endDate = format.parse("3.1.2013");
Days d = Days.daysBetween(new DateTime(startDate), new DateTime(endDate));
System.out.println(d.getDays());
Gives,
2
This is possible using Calendar class as well:
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
System.out.println(cal.fieldDifference(endDate, Calendar.DAY_OF_YEAR));
Gives,
2
This 2 can now be compared to your actual value (20).
The date is selected by the user using a drop down for year, month and day. I have to compare the user entered date with today's date. Basically see if they are the same date. For example
the user entered 02/16/2012. And if today is 02/16/2012 then I have to display a message. How do I do it?
I tried using milliseconds but that gives out wrong results.
And what kind of object are you getting back? String, Calendar, Date? You can get that string and compare it, at least that you think you'll have problems with order YYYY MM DD /// DD MM YYY in that case I suggest to create a custom string based on your spec YYYYMMDD and then compare them.
Date d1 = new Date();
Date d2 = new Date();
String day1 = d1.getYear()+"/"+d1.getMonth()+"/"+d1.getDate();
String day2 = d2.getYear()+"/"+d2.getMonth()+"/"+d2.getDate();
if(day1.equals(day2)){
System.out.println("Same day");
}
Dates in java are moments in time, with a resolution of "to the millisecond". To compare two dates effectively, you need to first set both dates to the "same time" in hours, minutes, seconds, and milliseconds. All of the "setTime" methods in a java.util.Date are depricated, because they don't function correctly for the internationalization and localization concerns.
To "fix" this, a new class was introduced GregorianCalendar
GregorianCalendar cal1 = new GregorianCalendar(2012, 11, 17);
GregorianCalendar cal2 = new GregorianCalendar(2012, 11, 17);
return cal1.equals(cal2); // will return true
The reason that GregorianCalendar works is related to the hours, minutes, seconds, and milliseconds being initialized to zero in the year, month, day constructor. You can attempt to approximate such with java.util.Date by using deprecated methods like setHours(0); however, eventually this will fail due to a lack of setMillis(0). This means that to use the Date format, you need to grab the milliseconds and perform some integer math to set the milliseconds to zero.
date1.setHours(0);
date1.setMinutes(0);
date1.setSeconds(0);
date1.setTime((date1.getTime() / 1000L) * 1000L);
date2.setHours(0);
date2.setMinutes(0);
date2.setSeconds(0);
date2.setTime((date2.getTime() / 1000L) * 1000L);
return date1.equals(date2); // now should do a calendar date only match
Trust me, just use the Calendar / GregorianCalendar class, it's the way forward (until Java adopts something more sophisticated, like joda time.
There is two way you can do it. first one is format both the date in same date format or handle date in string format.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String date1 = sdf.format(selectedDate);
String date2 = sdf.format(compareDate);
if(date1.equals(date2)){
}else{
}
Or
Calendar toDate = Calendar.getInstance();
Calendar nowDate = Calendar.getInstance();
toDate.set(<set-year>,<set-month>,<set-date->);
if(!toDate.before(nowDate))
//display your report
else
// don't display the report
Above answers are correct but consider using JodaTime - its much simpler and intuitive API.
You could set DateTime using with* methods and compare them.
Look at this answer
How do I add/subtract two time objects. I have two time objects (arrival and departure) in format of "yyyy/MMM/dd HH:mm:ss". I need to print the difference between departure and arrival time. I am generating time ad below:
public String getTime() {
Calendar currentDate = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MMM/dd HH:mm:ss");
return formatter.format(currentDate.getTime());
}
Can I get time in mills and than format it when I needed to print ?
Take a look at Joda Time library.
You can easily subtract and add DateTime and find out interval easily :
// interval from start to end
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);
Interval interval = new Interval(start, end);
something like this.....
public long getTimeDiff() throws Exception {
String arrival = "2011/Nov/10 13:15:24";
String departure = "2011/Jan/10 13:15:24";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MMM/dd HH:mm:ss");
java.util.Date date1 = formatter.parse(arrival);
java.util.Date date2 = formatter.parse(departure);
return date2.getTime() - date1.getTime();
}
Convert them to date and then to long and subtract, that would give the time difference in milli seconds,
Date d1 = DateFormat.parse(time1);
Date d2 = DateFormat.parse(time2);
long diffInMilliSeconds = d1.getTime()-d2.getTime();
You can get time in milliseconds for both calendars using getTime method. When you can convert the result of subtraction to measure units that you need. If you're going to work with time/duration seriously when take a look at Joda library
Upd. You should call getTime twice. First object being returned is Date, when you call getTime on Date you get long value.
I would convert the two time/Date objects in milliseconds. Then i would subtract them (we are dealing with longs).
Then i would create a Date object from the resulting long value. After that you can construct a Calendar with Calendar.setDate(Date).
Regards!
Yes, start with your Dates and use getTime() to convert to milliseconds (or getTimeInMillis() for your Calendars). That give you long values you can subtract. That's the easy part.
Then you can convert these milliseconds into a readable format yourself. But it probably makes sense to use a packaged library to do it.
Some folks like the Joda library for these types of date calculations. I find Commons Lang is fantastic. It provides DateUtils which is useful if you find you want to perform calculations like rounding or truncating your dates to the nearest minute or hour etc. The part that will be most useful to you is the DurationFormatUtils class which gives you functions like formatDurationHMS to format into nice Hour:Minute:Second display and formatDurationWords to get text (fancy!) or other similar functions to easily format your milliseconds into a nicely human-readable format.