Converting an integer to expected Date value in java [duplicate] - java

This question already has answers here:
Convert day of the year to a date in java
(2 answers)
Closed 3 years ago.
In the below Java class, I need to write the logic of converting an int to Date as explained below. And this program is not related to adding number of days to current date.
If endDay value is 1, then date should print as Jan 1st 2020.
If endDay value is 28, then date should print as Jan 28th 2020.
If endDay value is 35, then date should print as Feb 4th 2020.
If endDay value is 60, then date should print as Feb 29th 2020.
If endDay value is 70, then date should print as March 10th 2020.
Note: value of endDay (1) always starts from January 1st of every year.
import java.util.Date;
public class TestDate
{
public void startEndDate(int endDay)
{
Date date=new Date();
//logic to print the date here
System.out.println("For the given end day of "+endDay+" the date returned is : "+date);
}
public static void main(String[] args)
{
startEndDate(35);
startEndDate(49);
startEndDate(70);
}
}
Can any one suggest me the ideas on how to write the logic for above one ?

java.time and Year.atDay()
public static void startEndDate(int endDay)
{
LocalDate date = Year.of(2020).atDay(endDay);
System.out.println("For the given end day of " + endDay
+ " the date returned is : " + date);
}
Let’s try it out:
startEndDate(35);
startEndDate(49);
startEndDate(70);
Output is:
For the given end day of 35 the date returned is : 2020-02-04
For the given end day of 49 the date returned is : 2020-02-18
For the given end day of 70 the date returned is : 2020-03-10
The documentation of Year.atDay() explains:
Combines this year with a day-of-year to create a LocalDate.
Please fill in your desired year where I put 2020.
I recommend you don’t use Date. That class is poorly designed and long outdated. Instead I am using Year and LocalDate, both from java.time, the modern Java date and time API.
A comment suggested regarding your question as a question of adding a number of days to December 31 of the previous year. IMO regarding it as finding a date from the number of the day-of-year gives a somewhat more elegant solution.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of Year.atDay(int dayOfYear)
Documentation of LocalDate.ofYearDay(), a good alternative

Related

How can i change year with LocalDate by adding weeks?

Here is my code. This method works only for 1 ( current year). When week number is more than 53, dates start from dates in first week in current year but not the next.
Year has 52 or 53 weeks, so when week is last (52or53) i have 2020-12-28 - 2021-01-03, but when I want get first week of next year (2021-01-04 - 2021-01-10) it outputs me first week from 2020 ( 2019-12-30 - 2020-01-05).
public void showPreviousNextWeekDays(DataBaseHelper dataBaseHelper, long weekChange) {
if (weekChange >= 0) {
LocalDate ld = LocalDate.now().plusWeeks(weekChange);
final long weekNumber = ld.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); //takes week from current date
LocalDate firstDayOfWeek = ld.ofYearDay(ld.getYear(), (int)weekNumber)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
.with(DayOfWeek.MONDAY);
LocalDate lastDayOfWeek = ld.ofYearDay(ld.getYear(), (int)weekNumber)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
.with(DayOfWeek.SUNDAY);
String firstAndLastDayOfWeek = firstDayOfWeek.toString() + " - " + lastDayOfWeek.toString();
daysArrayAdapter = new ArrayAdapter<DayModel>(getActivity(), android.R.layout.simple_list_item_1, db.NextWeek(weekChange));
daysList.setAdapter(daysArrayAdapter);
How can i go forward with years also by adding weeks?
You are correct that your code is not correct. When I set weekChange to 14 and run today (September 29), I get 2019-12-30 - 2020-01-05 where expected result would be 2021-01-04 - 2020-01-10. Also for 15 and 16 weeks your code goes back to a week in the beginning of this year rather than finding a week in the beginning of next year as it should.
I suggest the following, which is also a bit simpler:
int weekChange = 14;
LocalDate ld = LocalDate.now(ZoneId.systemDefault()).plusWeeks(weekChange);
LocalDate firstDayOfWeek = ld.with(DayOfWeek.MONDAY);
LocalDate lastDayOfWeek = ld.with(DayOfWeek.SUNDAY);
String firstAndLastDayOfWeek = firstDayOfWeek.toString() + " - " + lastDayOfWeek.toString();
System.out.println(firstAndLastDayOfWeek);
Output when run today:
2021-01-04 - 2021-01-10
LocalDate uses the ISO calendar system including ISO weeks if not explicitly instructed otherwise. So we can be sure that ld.with(DayOfWeek.MONDAY) gives us Monday at the start of the same ISO week. Similarly ld.with(DayOfWeek.SUNDAY) gives us Sunday at the end of the ISO week. So there is nothing more to it.
What happened in your code?
Sticking to the case of weekChange 14 and running today.
ld becomes 2021-01-05 (Tuesday 14 weeks from now). This date is in week 1 of 2021, so weekNumber will be 1.
ofYearDay is a static method of LocalDate. So ld.ofYearDay(ld.getYear(), (int)weekNumber) gives you the same date as you would have got from LocalDate.ofYearDay(ld.getYear(), (int)weekNumber). It does not use ld for anything. Since weekNumber is 1, you get day 1 of 2021, so 2021-01-01. Passing the week number as the day of year to ofYearDay() is meaningless. 2021-01-01 happens to fall in week 53 of 2020. So with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber) adjusts the date back to week 1 of 2020. This is where we go a year wrong. The result is 2020-01-03. The Monday of that week is 2019-12-30, which explains why you got this as the first day of week in the output.
The last day of week is similar. And week numbers 2 and 3 are similar since you use the week number as a day of year, and January 2 and 3 fall in the last week of the previous year, 2020, too.
How did I find out? I ran your code in my debugger. There it was clear to see. If you haven’t yet learned to use a debugger. I suggest that now is the best of all times.

Java LocalDate How to get last week of year as 53rd week instead of 1st week of new year?

If you consider that week will start from Jan 01 of every year & week start is SUNDAY then there will be 53 weeks in 2019.
Following above Jan 29,30,31 2019 will be into Week-53 of 2019.
As given in documentation of IsoFields for WEEK_OF_WEEK_BASED_YEAR that all three fields are validated against their range of valid values. The week-of-week-based-year field is validated from 1 to 52 or 53 depending on the week-based-year.
So I'm assuming that following code should give the output as: WEEK_OF_WEEK_BASED_YEAR 53 & WEEK_BASED_YEAR 2019.
But it's giving output as: 1 & 2020
import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.IsoFields;
public class WeekStartDemo {
public static void main(String args[]) {
DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
.ofPattern("uuuu-MM-dd")
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
LocalDate updatedDate = LocalDate.parse("2019-12-30", DATE_FORMATTER);
System.out.println(updatedDate.toString());
System.out.println(updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
System.out.println(updatedDate.get(IsoFields.WEEK_BASED_YEAR));
}
}
If I pass the date as 2019-12-28 then it's returning WEEK_OF_WEEK_BASED_YEAR 52 & WEEK_BASED_YEAR 2019. But doesn't work for last week of 2019 (which is 53rd week)
Let me know what I'm missing in above code.
As I mentioned in the comments, and from your Javadoc link for IsoFields, The week-based-year itself is defined relative to the standard ISO proleptic year. It differs from the standard year in that it always starts on a Monday (not a Sunday). It should be easy enough to find the years with 53 weeks using your posted code, iterate from 1900 to 2300 and parse the WEEK_OF_WEEK_BASED_YEAR for the last day of the given year and print the values where it is 53. Like,
DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd")
.withChronology(IsoChronology.INSTANCE)
.withResolverStyle(ResolverStyle.STRICT);
for (int i = 1900; i < 2300; i++) {
LocalDate updatedDate = LocalDate.parse(String.format("%d-12-31", i), DATE_FORMATTER);
if (updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) == 53) {
System.out.println(i);
}
}
The first few values I get are
1903
1908
1914
1920
1925
1931
1936
1942
skipping ahead a bit...
2009
2015
2020
2026
So this year (2020) has 53 weeks, and 2019 does not.
LocalDate date = LocalDate.of(2019, Month.DECEMBER, 30);
int weekOfYear = date.get(WeekFields.SUNDAY_START.weekOfYear());
System.out.println(weekOfYear);
Output from this snippet is:
53
I believe that this is the exact difference between WeekFields.weekOfWeekBasedYear() and WeekFields.weekOfYear().
It may also be that your main source of confusion is using the wrong week fields, as Elliott Frisch also mentioned. The ISO week fields that you use define Monday as the first day of the week and week one of the year as the first week containing at least 4 days of the year. In contrast you said that you wanted:
If you consider that week will start from Jan 01 of every year &
week start is SUNDAY …
From your comments:
… will the new week (Week-01) will always start on Jan 01 of every year ?
Yes it will.
How can I perform minus 1 week on this weekOfYear ? As for Jan
01,2020, weekOfYear will be Week-01 2020. What type of minus 1
week I can perform to get weekOfYear as Week-53 2019 ? I tried
with date.minusWeeks(1) but it returns Week-52 2019
LocalDate dateInWeek1 = LocalDate.of(2020, Month.JANUARY, 3);
int weekOfYear = dateInWeek1.get(wf.weekOfYear());
System.out.println(weekOfYear);
LocalDate dateInPreviousWeek;
if (weekOfYear == 1) {
dateInPreviousWeek = dateInWeek1.minusWeeks(1)
.with(TemporalAdjusters.lastDayOfMonth());
}
else {
dateInPreviousWeek = dateInWeek1.minusWeeks(1);
}
System.out.format("%s %2d%n", dateInPreviousWeek, dateInPreviousWeek.get(wf.weekOfYear()));
We need to handle the case of week 1 specially. When subtracting 1 week, we know we are getting into December the previous year. Selecting the last day of the month will give us December 31. This will always be in the last week of the year (usually week 53; occasionally week 54 if in a leap year that begins on a Saturday, I think that years 2000 and 2028 are examples of this).
The issue here is that a given year has either 365 or 366 days (the latter for a leap year), which means that every year has either 1 or 2 days extra beyond 52 weeks. The ISO system for week years is what handles this, and it means that sometimes the first week of the year might not start of the 1st of January, nor would the last day of a year fall in the 52nd week. One workaround here would be to just calculate the week starting from the beginning of each year, e.g.
LocalDate firstOfYear = LocalDate.of(2019, Month.JANUARY, 1);
LocalDate updatedDate = LocalDate.of(2019, Month.DECEMBER, 30);
int diff = (int)ChronoUnit.DAYS.between(firstOfYear, updatedDate);
int week = 1 + (diff / 7);
System.out.println("The week number is: " + week);
Based on the ISO-8601 (https://www.cl.cam.ac.uk/~mgk25/iso-time.html) this is correct. 2019 has no calendarweek 53. Week 01 of a year is per definition the first week that has the Thursday in this year, which is equivalent to the week that contains the fourth day of January.
As far as I know this is done to avoid a cw 1 without a workday.

last date of previous month returning 30 days for May

I am using the below code to retrieve the last day in the previous month - Ex: May. But it is returning 30 days instead of 31.
The code given below
package net.vcmg.date;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
public class LastDayPreviousMonth {
public static void main(String[] args) {
Date lastDateOfPreviousMonth = addMonths(lastDayOfTheMonth(today()), -1);
System.out.println("lastDateOfPreviousMonth: "+lastDateOfPreviousMonth);
}
//the below method is from Utils.java
public static Date lastDayOfTheMonth(Date d) {
Calendar cal = Calendar.getInstance();
cal.setTime(d);
int actualMax = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, actualMax);
return cal.getTime();
}
public static Date addMonths(Date date, int numMonths)
{
return DateUtils.addMonths(date, numMonths);
}
public static Date today()
{
return truncDate(now());
}
public static Date now()
{
// will cut-off milliseconds
return new Date( (System.currentTimeMillis()/1000) * 1000);
}
public static Date truncDate (Date date) {
return DateUtils.truncate(date, Calendar.DATE);
}
}
Here, when i call the lastDateOfPreviousMonth in the main method, it is returning 30 days alone. Not the 31 , May contains 31 days actually. Please help.
Java 8
If you are not constraint to use the old Date it will be better to use the new java.time.LocalDate
LocalDate previousMonth = LocalDate.now().minusMonths(1);
LocalDate start = previousMonth.withDayOfMonth(1);
LocalDate end = previousMonth.withDayOfMonth(previousMonth.lengthOfMonth());
System.out.println(start);
System.out.println(end);
Output
2019-05-01
2019-05-31
Edit
For your implementation, change the order of methods
addMonths - get the current date and provide the previous month addMonths(new Date(), -1)
lastDayOfTheMonth - get the last day of the previous month lastDayOfTheMonth(addMonths(new Date(), -1))
Date lastDateOfPreviousMonth = lastDayOfTheMonth(addMonths(new Date(), -1));
Output
lastDateOfPreviousMonth: Fri May 31 10:46:13 EEST 2019
Try this:
public static void main(String[] args) {
Date lastDateOfPreviousMonth = lastDayOfTheMonth(addMonths(today(), -1));
System.out.println("lastDateOfPreviousMonth: " + lastDateOfPreviousMonth);
}
When you call lastDayOfTheMonth for today() day will be 30. And after minus one month result expected will be 30, not 31.
It’s a logical error in the way you have thought out your program/algorithm. You are first finding the last day of the month, in this case June 30. You are then subtracting 1 month. That gives May 30 regardless of the fact that there are 31 days in May (it’s not explicit from the documentation of DateUtils.addMonths that it works this way, but it uses the poorly designed and outdated Calendar class internally, so this is what we should expect).
Instead do things in the opposite order. First find the previous month:
YearMonth lastMonth = YearMonth.now(ZoneId.of("Asia/Kolkata")).minusMonths(1);
2019-05
Since the new month doesn’t begin at the same point in time in all time zones, I recommend that you state your desired time zone as shown.
Only then find the last day of the month:
LocalDate lastDayOfLastMonth = lastMonth.atEndOfMonth();
2019-05-31
Avoid Date and Calendar
I recommend you don’t use Date and Calendar. Those classes are poorly designed and long outdated. Instead use LocalDate and other classes from java.time, the modern Java date and time API. This will also save you from the external dependency on Apache DateUtils since its functionality is generally built into the modern classes.
Links
Documentation of org.apache.commons.lang3.time.DateUtils.addMonths
Oracle tutorial: Date Time explaining how to use java.time.

Why there is a difference between GregorianCalendar.getTimeInMillis() and GregorianCalendargetTimeInMillis(1970.01.01)) [duplicate]

This question already has answers here:
How do I calculate someone's age in Java?
(28 answers)
Why is January month 0 in Java Calendar?
(18 answers)
Closed 3 years ago.
I have tried to compare to Dates the Birthdate and the Current date
and then I tried to get the age.
But the Current date Funtion begins with another Date than the given date
My Code:
GregorianCalendar birthdate = new GregorianCalendar(2001,06,20);
long ms = System.currentTimeMillis() - birthdate.getTimeInMillis();
double years = (((double)ms / 1000)/31536000) ;
System.out.print(years);
// years Shoud be 18 here but it returns 17.3
if (years > 18) {
// Code Block
}
else{
System.out.print("to Jung");
}
Check the Constructor on GregorianCalendar.
public GregorianCalendar(int year,
int month,
int dayOfMonth)
Constructs a GregorianCalendar with the given date set in the default time zone with the default locale.
year - the value used to set the YEAR calendar field in the calendar.
month - the value used to set the MONTH calendar field in the calendar. Month value is 0-based. e.g., 0 for January.
dayOfMonth - the value used to set the DAY_OF_MONTH calendar field in the calendar.
You are creating a July 20th date, which is coincidentally offset by a single month, or approximately 0.08 years.
LocalDate birthdate = LocalDate.of(2001,06,20);
LocalDate currentdate = LocalDate.now();
int years = Period.between(birthdate , currentdate).getYears();
if (years >= 18) {
// Code
} else {
System.out.print("Sie sind zu Jung");
}
It Worked like this but I must change the hole code because everything was written with the GeorgianCalender.
I couldn't tell you why exactly your code, which should technically work, doesn't: there seems to be inaccuracies (leap days?) in the Calendar, or I'm missing something. Thanks to Compass, I know that I was missing something: months are 0-indexed in the constructor for Gregorian Calendar. 06 is July.
However, you shouldn't compare dates like this. If you don't want to use any other library, you can do this:
GregorianCalendar birthdate = new GregorianCalendar(2001,06,20);
GregorianCalendar today = new GregorianCalendar();
birthdate.add(Calendar.YEAR, 18);
System.out.print(birthdate.getTime().after(today.getTime()));

Check current date java [duplicate]

This question already has answers here:
Compare two dates in Java
(13 answers)
Closed 4 years ago.
From java class Date docs:
before(Date when) Tests if this date is before the specified date.
When I use this method to test whether selected date is equal to today, I get wrong output message.
public class JavaApplication28 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws NoSuchAlgorithmException, ParseException {
Date date1;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String statusDT ="2018-04-08";
date1 = formatter.parse(statusDT);
if (date1.equals(new Date())) {
System.out.println("today");
} else if (date1.before(new Date())) {
System.out.println("wrong");
}
}
}
This is date1, which is today date
Sun Apr 08 00:00:00 MYT 2018
The equal method look not functiong as well
equals(Object obj) Compares two dates for equality.
The given date date1 represent today but with midnight time : Sun Apr 08 00:00:00 MYT 2018
the date used for comparison new Date() represents also today but the actual time (about 15h10) : Sun Apr 08 15:10:00 MYT 2018
So date1 if before actual Date() and it goes in the good if section
As the Java8 introduce a new Date API, it's easier to use in most case :
LocalDateTime which holds Date (day/month/year) and Time (sec/min/hour)
LocalDate which holds the Date part and can be given from a LocalDateTime.toLocalDate()
LocalTime which holds the Time part and can be given from a LocalDateTime.toLocalTime()
So if you don't matter of the time, and just want to check the day/month/year you can use only the LocalDate part from the LocalDateTime :
if (date1.toLocalDate().equals(LocalDate.now())) {
System.out.println("today"); //< ---
} else if (date1.toLocalDate().isBefore(LocalDate.now())) {
System.out.println("before now");
} else if (date1.toLocalDate().isAfter(LocalDate.now())) {
System.out.println("after now");
}
Try this :
long l1 = date1.getTime();
long l2 = (new Date()).getTime();
Output
1523142000000
1523192849177
The doc said :
Compares two dates for equality. The result is true if and only if the
argument is not null and is a Date object that represents the same
point in time, to the millisecond, as this object. Thus, two Date
objects are equal if and only if the getTime method returns the same
long value for both.
Your get wrong because you thing that equal compare only the date part, but NO, it also compare the time part
Another Solution
Because you are using Java 8 why not using java.time instead like this :
String statusDT = "2018-04-08";
LocalDate date = LocalDate.parse(statusDT, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
if (date.isEqual(LocalDate.now())) {
System.out.println("today");
} else if (date.isBefore(LocalDate.now())) {
System.out.println("before");
} else {
System.out.println("after");
}
Class java.util.Date contains both a date and a time-of-day - as can be seen in the output of your program. The Date you obtain by parsing the String has no time-of-day, only a date. In other words, its time-of-day is 00:00 (i.e. midnight). Hence the two Dates are not equeal.
And by the way, the link you provided for the javadoc of the Date class is the Java 8 documentation. If this means you are using Java 8, then there is a new Date-Time API. There is a tutorial at
https://docs.oracle.com/javase/tutorial/datetime/index.html

Categories

Resources