This question already has answers here:
Get the weeknumber from a given date in Java FX
(4 answers)
Closed 8 years ago.
I'm trying to get the Week Number of a full LocalDate with the format:
dd.MM.yyy
I haven't found a function in the Java 8 Date API wich returns the Week Number and i have tried to create a algorithm, but it did'nt work.
One small warning. I haven't tested this yet, but looking at the API documentation of WeekFields and LocalDate.get, you should do something like:
LocalDate date = ...;
// Or use a specific locale, or configure your own rules
WeekFields weekFields = WeekFields.of(Locale.getDefault());
int weekNumber = date.get(weekFields.weekOfWeekBasedYear());
The answer of Mark Rotteveel is almost right and again an example which kind of confusion potential there is in the class WeekFields (similar sounding method names, but deviating from intuitive civil usage). The right code requires another field:
LocalDate date = LocalDate.now();
TemporalField woy = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear();
int weekNumber = date.get(woy);
See also the similar debate on this SO-post, especially the discussion and comments about the answer of #kleopatra.
Related
This question already has an answer here:
ZonedDateTime change behavior jdk 8/11
(1 answer)
Closed 2 years ago.
I am trying to parse dates from strings to ZonedDateTimes and I've come across a bizzare problem.
2020-11-01T01:00-05:00[America/New_York]
This is an hour right after time EDT ends this year. When I pass it to ZonedDateTime.parse I get
ZonedDateTime.parse("2020-11-01T01:00-05:00[America/New_York]")
// 2020-11-01T01:00-04:00[America/New_York]
but if I do
ZonedDateTime.parse("2020-11-01T01:00-04:00[America/New_York]").plusHours(1)
I get
2020-11-01T01:00-05:00[America/New_York]
So it's not like Java cannot represent this ambiguous value or something..
Can anyone explain to me that behavior and possible solution?
Note: I am using Java 8
As Amir Schnell said in the comments, this seems to be a bug in the JDK, as they cannot reproduce this in Java 11.
For now, I have found this work around:
Parse the string into a local date time, zone ID, and zone offset, and create a ZonedDateTime using those three things:
TemporalAccessor ta = DateTimeFormatter.ISO_ZONED_DATE_TIME.parse("2020-11-01T01:00-05:00[America/New_York]");
System.out.println(
ZonedDateTime.ofLocal(
LocalDateTime.from(ta),
ZoneId.from(ta),
ZoneOffset.from(ta)
)
);
I searched on StackOverflow for the same, but all the answers are for legacy java versions.
I did not find any of the answers with Java 8 Data and Time utility.
Can anybody help me out for the same?
I find out a way using LocalDate and TemporalAdjuster's with() method as follows:
LocalDate firstSundayOfNextMonth = LocalDate
.now()
.with(firstDayOfNextMonth())
.with(nextOrSame(DayOfWeek.SUNDAY));
This question already has answers here:
How to add days to a date in Java
(3 answers)
Closed 7 years ago.
So I have a URL that contains date=2016-01-25 somewhere in between. My goal is, when a user enters the URL and n days (in a GUI application's text fields), it should go into a loop of n times and increment the date from the URL. That also means it goes to the next month if it is 30/31. Anyone have an optimized approach to this?
Assuming you are using Java 8, you can use the java.time.LocalDate class to parse, add days, and convert back to a string. Here's an example:
String date = "2016-01-25";
LocalDate localDate = LocalDate.parse(date);
localDate = localDate.plusDays(15);
System.out.println(localDate); // Prints "2016-02-09"
To add to the Java 8 solutions, if you're using an earlier version of Java you can use JodaTime's LocalDate class to accomplish the same thing. Syntax will be the same as in Java 8.
You would need to parse the date string out of the URL, using something like regex and then create a Date object increment your date and rebuild the URL.
Java's Date primitives such as LocalDate have support for "plusDays(int n)"
I have a date in the far past.
I found out what the duration is between this date and now.
Now I would like to know - how much is this in years?
I came up withthis solution using Java8 API.
This is a monstrous solution, since I have to convert the duration to Days manually first, because there will be an UnsupportedTemporalTypeException otherwise - LocalDate.plus(SECONDS) is not supported for whatever reason.
Even if the compiler allows this call.
Is there a less verbous possibility to convert Duration to years?
LocalDate dateOne = LocalDate.of(1415, Month.JULY, 6);
Duration durationSinceGuss1 = Duration.between(LocalDateTime.of(dateOne, LocalTime.MIDNIGHT),LocalDateTime.now());
long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(),
LocalDate.now().plus(
TimeUnit.SECONDS.toDays(
durationSinceGuss1.getSeconds()),
ChronoUnit.DAYS) );
/*
* ERROR -
* LocalDate.now().plus(durationSinceGuss1) causes an Exception.
* Seconds are not Supported for LocalDate.plus()!!!
* WHY OR WHY CAN'T JAVA DO WHAT COMPILER ALLOWS ME TO DO?
*/
//long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(), LocalDate.now().plus(durationSinceGuss) );
/*
* ERROR -
* Still an exception!
* Even on explicitly converting duration to seconds.
* Everything like above. Seconds are just not allowed. Have to convert them manually first e.g. to Days?!
* WHY OR WHY CAN'T YOU CONVERT SECONDS TO DAYS OR SOMETHING AUTOMATICALLY, JAVA?
*/
//long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDate.now(), LocalDate.now().plus(durationSinceGuss.getSeconds(), ChronoUnit.SECONDS) );
Have you tried using LocalDateTime or DateTime instead of LocalDate? By design, the latter does not support hours/minutes/seconds/etc, hence the UnsupportedTemporalTypeException when you try to add seconds to it.
For example, this works:
LocalDateTime dateOne = LocalDateTime.of(1415, Month.JULY, 6, 0, 0);
Duration durationSinceGuss1 = Duration.between(dateOne, LocalDateTime.now());
long yearsSinceGuss = ChronoUnit.YEARS.between(LocalDateTime.now(), LocalDateTime.now().plus(durationSinceGuss1) );
System.out.println(yearsSinceGuss); // prints 600
Although the accepted answer of #Matt Ball tries to be clever in usage of the Java-8-API, I would throw in following objection:
Your requirement is not exact because there is no way to exactly convert seconds to years.
Reasons are:
Most important: Months have different lengths in days (from 28 to 31).
Years have sometimes leap days (29th of February) which have impact on calculating year deltas, too.
Gregorian cut-over: You start with a year in 1415 which is far before first gregorian calendar reform which cancelled full ten days, in England even 11 days and in Russia more. And years in old Julian calendar have different leap year rules.
Historic dates are not defined down to second precision. Can you for example describe the instant/moment of the battle of Hastings? We don't even know the exact hour, just the day. Assuming midnight at start of day is already a rough and probably wrong assumption.
Timezone effects which have impact on the length of day (23h, 24h, 25h or even different other lengths).
Leap seconds (exotic)
And maybe the most important objection to your code:
I cannot imagine that the supplier of the date with year 1415 has got the intention to interprete such a date as gregorian date.
I understand the wish for conversion from seconds to years but it can only be an approximation whatever you choose as solution. So if you have years like 1415 I would just suggest following very simple approximation:
Duration d = ...;
int approximateYears = (int) (d.toDays() / 365.2425);
For me, it is sufficient in historic context as long as we really want to use a second-based duration for such an use-case. It seems you cannot change the input you get from external sources (otherwise it would be a good idea to contact the duration supplier and ask if the count of days can be supplied instead). Anyway, you have to ask yourself what kind of year definition you want to apply.
Side notes:
Your complaint "WHY OR WHY CAN'T JAVA DO WHAT COMPILER ALLOWS ME TO DO?" does not match the character of new java.time-API.
You expect the API to be type-safe, but java.time (JSR-310) is not designed as type-safe and heavily relies on runtime-exceptions. The compiler will not help you with this API. Instead you have to consult the documentation in case of doubt if any given time unit is applicable on any given temporal type. You can find such an answer in the documentation of any concrete implementation of Temporal.isSupported(TemporalUnit). Anyway, the wish for compile-safety is understandable (and I have myself done my best to implement my own time library Time4J as type-safe) but the design of JSR-310 is already set in stone.
There is also a subtile pitfall if you apply a java.time.Duration on either LocalDateTime or Instant because the results are not exactly comparable (seconds of first type are defined on local timeline while seconds of Instant are defined on global timeline). So even if there is no runtime exception like in the accepted answer of #Matt Ball, we have to carefully consider if the result of such a calculation is reasonable and trustworthy.
Use Period to get the number of years between two LocalDate objects:
LocalDate before = LocalDate.of(1415, Month.JULY, 6);
LocalDate now = LocalDate.now();
Period period = Period.between(before, now);
int yearsPassed = period.getYears();
System.out.println(yearsPassed);
This question already has answers here:
Importing two classes with same name. How to handle?
(12 answers)
Closed 7 years ago.
I'm practicing on how to work with dates. But i got stuck when i want to use a javafx datepicker. since it only works with java.time.LocalDate i was trying something like this.
// here i import java.time.LocalDate to get the date from the datepicker;
LocalDate dueDate = datepickerInvoiceDueDate.getValue();
int year = dueDate.getYear();
int month = dueDate.getMonthValue();
int day = dueDate.getDayOfMonth();
//but here i want to import org.joda.time.LocalDate;
LocalDate dueDatejt = new LocalDate(year, month, day);
Is there a workaround for this ?
And is it possible to store Localdate (joda time) inside mysql database ?
I found a temporary fix but i do not think this is the right way ?
java.time.LocalDate dueDate = datepickerInvoiceDueDate.getValue();
int year = dueDate.getYear();
int month = dueDate.getMonthValue();
int day = dueDate.getDayOfMonth();
//import org.joda.time.LocalDate;
LocalDate dueDatejt = new LocalDate(year, month, day);
The author of both libraries writes on the Joda-Time-website:
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).
So it is clear you should use the workaround to fully qualify the classnames of Joda-Time only as temporary solution. Instead the intention and official recommendation is to migrate on Java-8-platforms.
Although there is usually no 1:1-migration (some effort is necessary!), the fact that Joda-Time will not be any longer in real development (abandoning many new features, just bugfixing) is a strong argument for migration. Another strong argument in favor of migration is the missing interoperability of Joda-Time with Java-8. The author had got the original plan to support low-level-interfaces like TemporalAccessor but dropped it (probably due to lack of resources). What does this concept mean? Concrete example for interoperability (leaving aside the somehow annoying fact to write fully qualified class names):
With TemporalAccessor-Support you could write:
org.joda.time.LocalDate joda = new org.joda.time.LocalDate(year, month, day);
java.time.LocalDate date = java.time.LocalDate.from(joda);
But actually you must write:
org.joda.time.LocalDate joda = new org.joda.time.LocalDate(year, month, day);
java.time.LocalDate date = java.time.LocalDate.of(joda.getYear(), joda.getMonthOfYear(), joda.getDayOfMonth());
So it is obvious that it is no good idea to support both libraries at the same time in your application.
I think u mean LocalDate dueDatejt = new LocalDate(year, month, day); in your "temporary fix" which is just correct code.
If u want some more definitive way of doing, I would suggest getting rid of Joda time dates, since new java 8 dates have been implemented by the creator of Joda time, you will find just the same functionnalities in a very similar API.
About inserting dates into database, u can insert dates of any type, provided u convert them to java.sql.Date (or java.sql.Timestamp/java.sql.Time) before.
For a standard java.time.LocalDate, you can do : java.sql.Date sqlDate = java.sql.Date.valueOf(dueDate);