LocalDateTime now = LocalDateTime.now();
How or where do I proceed from this line of code?
you can do it:
LocalDateTime.now().minusHours(new Random().nextInt(24));
if you need you similarly can add .minusMinutes(new Random().nextInt(60)) or .minusSeconds(new Random().nextInt(60))
This function gives you a LocalDateTime within the last 24 hours. The random value is been taken based on the seconds of 24 hours:
import java.time.*;
import java.util.concurrent.ThreadLocalRandom;
public LocalDateTime randomLast24Hours() {
Long secondsOfDay = Duration.ofDays(1).getSeconds();
Long randomSeconds = ThreadLocalRandom.current().nextLong(secondsOfDay + 1);
return LocalDateTime.now().minusSeconds(randomSeconds);
}
Yeah I just saw that ChristianB posted a more random solution but im just gonna leave this here in case someone needs just random hours.
public static LocalDateTime minusRandomHours(int inputHours) {
int hours = new Random().nextInt(inputHours);
LocalDateTime randomTime = LocalDateTime.now().minusHours(hours);
return randomTime;
}
If you would like to code something more customizable or return especific info from a time you can use the Java Calendar Class, for example:
import java.util.Caldenar;
Calendar c = Calendar.getInstance();
int hour_now = c.get(Calendar.HOUR_OF_DAY); // returns the hour now as integer
Also, by using the LocalDate.of() and the getDayOfWeek().name() function is possible to get the name of the day. For example:
import java.time.LocalDate;
String name_day = LocalDate.of(2021, 01, 10).getDayOfWeek().name();
My code outputs the random time like this:
Check it out....
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Random;
public class randLast24Hours {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
Random rand = new Random();
int rand_hour;
int rand_minutes;
int today = c.get(Calendar.DAY_OF_MONTH); // get today's day of the month
int hour_now = c.get(Calendar.HOUR_OF_DAY); // hour now
int minutes_now = c.get(Calendar.MINUTE); // minutes now
int rand_day = rand.nextInt(2) + today - 1; // rand between yesterday & today
String name_day = LocalDate.of(2021, 01, rand_day).getDayOfWeek().name();
int rand_hour_yesterday = rand.nextInt(23-hour_now) + hour_now;
int rand_hour_today = rand.nextInt(hour_now+1);
// choose rand_hour and rand_minutes depending on what's the rand_day
if(rand_day == today){rand_hour = rand_hour_today;
rand_minutes = rand.nextInt(minutes_now);}
else {rand_hour = rand_hour_yesterday;
rand_minutes = rand.nextInt(60);}
int rand_seconds = rand.nextInt(60);
System.out.println("Random time for the last 24hrs:");
System.out.print(name_day+" ");if(rand_hour < 10) {System.out.print("0");}
System.out.print(rand_hour+":");if(rand_minutes < 10) {System.out.print("0");}
System.out.print(rand_minutes+":");if(rand_seconds < 10) {System.out.print("0");}
System.out.print(rand_seconds);}}
I'm trying to break a range of dates into equal intervals. Here is the code that I'm using. (Dates are in YYYY-MM-dd format)
Integer frequency= 4;
Date startDate = '2020-02-27';
Date endDate = '2022-02-26';
String[] startD = string.valueOf(behadelPlan.Start_datum__c).split('-');
String[] endD = string.valueOf(behadelPlan.Einddatum__c).split('-');
//String[] dates;
Integer x = 0;
Integer startYear = Integer.valueof(startD[0]);
Integer endYear = Integer.valueof(endD[0]);
//while (x < 4) {
for (Integer i = startYear; i <= endYear; i++) {
Integer endMonth = i != endYear ? 11 : Integer.valueof(endD[1]) - 1;
Integer startMon = i == startYear ? Integer.valueof(startD[1]) - 1 : 0;
for (Integer j = startMon; j <= endMonth && x < frequency; j = j + 1) {
Integer month = j + 1;
String displayMonth;
if (month < 10) {
displayMonth = '0' + month;
} else {
displayMonth = String.valueOf(month);
}
List<string> slist = new string[]{string.valueOf(i), displayMonth, '01'};
string allstring = string.join(sList,'-');
System.debug(slist);
x+=1;
}
}
when I run this I get the output as
2020-02-01
2020-03-01
2020-04-01
2020-05-01
Here In my case, I want to generate the dates at equal(monthly with the day being start dates day) intervals. In the above example, I should be getting the resultant dates as 4 equal intervals (as I've given my frequency in a number of months).
Please let me know on how can I achieve this.
Here is a simple example.
startdate = '2020-01-01'
endDate = '2020-12-01'
frequency = 4
output should be
2020-01-01
2020-03-01
2020-06-01
2020-09-01
Here is how I would do it. I will us class Calendar for this.
public class FrequencyTransform {
public static void main (String[] args) {
System.out.println("Split a date into equal intervals based on a given frequency");
Integer frequency= 4;
try {
Date startDate = new SimpleDateFormat("yyyy-mm-dd").parse("2020-02-27");
Date endDate = new SimpleDateFormat("yyyy-mm-dd").parse("2021-02-26");
Calendar startCalendar = Calendar.getInstance();
startCalendar.clear();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.clear();
endCalendar.setTime(endDate);
// id you want the interval to be months
int monthsElapsed = elapsed(startCalendar, endCalendar, Calendar.MONTH);
System.out.println("Number of months between dates:" + monthsElapsed);
int interval = monthsElapsed % frequency;
System.out.println("For the frequency 4 the interval is: " + interval);
while (!startCalendar.after(endCalendar)){
startCalendar.add(Calendar.MONTH,interval);
Date auxDate= startCalendar.getTime();
System.out.println(auxDate);
}
}
catch (ParseException ex) {
ex.printStackTrace();
}
}
private static int elapsed(Calendar before, Calendar after, int field) {
Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
int elapsed = -1;
while (!clone.after(after)) {
clone.add(field, 1);
elapsed++;
}
return elapsed;
}
}
This is just a quick example. You can take it from here. The thing is Calendar allow you to use different time units. Instead of Calendar.MONTH you can use Calendar.DATE for days, Calendar.YEAR for year. Wasn't very sure how you wanted to do the split.
Sample code ,
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SOTest {
static DateFormat dateFormat = new SimpleDateFormat("yyy-MM-dd");
public static void main(String[] args) {
try {
String startDateString = "2020-01-01";
String endDateString = "2020-12-01";
int frequency = 4;
Date startDate = (Date)dateFormat.parse(startDateString);
Date endDate = (Date)dateFormat.parse(endDateString);
Long intervalSize = (endDate.getTime()-startDate.getTime())/frequency;
for(int i=0; i<= frequency && intervalSize > 0; i++) {
Date date = new Date(startDate.getTime()+intervalSize*i);
System.out.println("Date :: "+dateFormat.format(date));
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
output for above ::
Date :: 2020-01-01
Date :: 2020-03-24
Date :: 2020-06-16
Date :: 2020-09-08
Date :: 2020-12-01
For input :: startDate = '2020-02-27' , endDate = '2022-02-26', interval = 4
Date :: 2020-02-27
Date :: 2020-08-27
Date :: 2021-02-26
Date :: 2021-08-27
Date :: 2022-02-26
I have to create algorithm to compute the chunk monthly given two dates.
example (format date: yyyy-MM-dd hh:mm:ss) given two dates:
startTime: : 2020-01-10 13:00:25
endTime : 2020-03-19 15:00:30
I have to divide in chunk monthly the period above.
In a nutshell if I compute the chunks would be :
chunk_1 --> from: 2020-01-10 13:00:25 to: 2020-01-31 23:59:59
chunk_2 --> from: 2020-02-01 00:00:00 to: 2020-02-29 23:59:59
chunk_3 --> from: 2020-03-01 00:00:00 to: 2020-03-19 15:00:30
my first solution is the followed:
public static List<ExportDateSegment> datesBetweenWithCalendar(Date d1, Date d2) {
List<ExportDateSegment> dateSegments = new ArrayList<ExportDateSegment>();
Calendar c1 = Calendar.getInstance();
c1.setTime(d1);
int monthsDiff = mounthsDiffbetween(d1, d2);
LOGGER.debug("months between two dates: {} ",monthsDiff);
int i = 1;
while (c1.getTimeInMillis() < d2.getTime()) {
Calendar calendar;
ExportDateSegment exportDateSegment = new ExportDateSegment();
LOGGER.debug("last day of the month: " + c1.getActualMaximum(Calendar.DATE) + " last hour of the month: "
+ c1.getActualMaximum(Calendar.HOUR_OF_DAY) + " first day of the month: "
+ c1.getActualMinimum(Calendar.DAY_OF_MONTH) + " month: " + (c1.get(Calendar.MONTH) + 1));
// the logic is to separate the three cases: the start period, intermediate period and the end period
if (i == 1) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(c1.getTime());
exportDateSegment.setEndDate(calendar.getTime());
} else if (i == monthsDiff) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
exportDateSegment.setStartDate(calendar.getTime());
exportDateSegment.setEndDate(d2);
} else {
Calendar startCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
Calendar endCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(startCalendar.getTime());
exportDateSegment.setEndDate(endCalendar.getTime());
}
c1.add(Calendar.MONTH, 1);
dateSegments.add(exportDateSegment);
i = i + 1;
}
return dateSegments;
}
public static int mounthsDiffbetween(Date d1, Date d2) {
int monthsDiff = 0;
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
monthsDiff = (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH)) + 1;
return monthsDiff;
}
ExportDateSegment is the bean that contains
startDate and endDate as attributes, in other words are the chunk.
Is there a smarter solution ?
You should use the Java 8 Time API, e.g. like this:
static List<TemporalRange<LocalDateTime>> chunkMonthly(LocalDateTime start, LocalDateTime end) {
List<TemporalRange<LocalDateTime>> list = new ArrayList<>();
for (LocalDateTime chunkEnd = end, chunkStart; ! chunkEnd.isBefore(start); chunkEnd = chunkStart.minusSeconds(1)) {
chunkStart = chunkEnd.toLocalDate().withDayOfMonth(1).atStartOfDay();
if (chunkStart.isBefore(start))
chunkStart = start;
list.add(new TemporalRange<>(chunkStart, chunkEnd));
}
Collections.reverse(list);
return list;
}
class TemporalRange<T extends TemporalAccessor> {
private final T start;
private final T end;
public TemporalRange(T start, T end) {
this.start = start;
this.end = end;
}
public T getStart() {
return this.start;
}
public T getEnd() {
return this.end;
}
#Override
public String toString() {
return this.start + " to " + this.end;
}
public String toString(DateTimeFormatter fmt) {
return fmt.format(this.start) + " to " + fmt.format(this.end);
}
}
Test
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
List<TemporalRange<LocalDateTime>> list = chunkMonthly(
LocalDateTime.parse("2020-01-10 13:00:25", fmt),
LocalDateTime.parse("2020-03-19 15:00:30", fmt));
list.forEach(r -> System.out.println(r.toString(fmt)));
Output
2020-01-10 13:00:25 to 2020-01-31 23:59:59
2020-02-01 00:00:00 to 2020-02-29 23:59:59
2020-03-01 00:00:00 to 2020-03-19 15:00:30
You should definitely use the java.time classes to do this. There are built in TemporalAdjusters that help you find the first and last day of a month.
public static List<ExportDateSegment> splitIntoMonths(LocalDateTime start, LocalDateTime end) {
LocalDate segmentEndDate =
start.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate();
LocalTime segmentEndTime = LocalTime.of(23, 59, 59);
LocalDate lastSegmentStartDate = end.with(TemporalAdjusters.firstDayOfMonth()).toLocalDate();
LocalTime segmentStartTime = LocalTime.of(0, 0, 0);
if (lastSegmentStartDate.isBefore(segmentEndDate)) { // start & end are in the same month
return Collections.singletonList(new ExportDateSegment(start, end));
}
ArrayList<ExportDateSegment> list = new ArrayList<>();
// adds the first segment, which is not a whole month
list.add(new ExportDateSegment(start, LocalDateTime.of(segmentEndDate, segmentEndTime)));
// just like a typical for loop, but with LocalDate
for (LocalDate segmentStartDate = segmentEndDate.plusDays(1) ; segmentStartDate.isBefore(lastSegmentStartDate) ; segmentStartDate = segmentStartDate.plusMonths(1)) {
list.add(new ExportDateSegment(
LocalDateTime.of(segmentStartDate, segmentStartTime),
LocalDateTime.of(segmentStartDate.with(TemporalAdjusters.lastDayOfMonth()), segmentEndTime)
));
}
// adds the last segment, which is also not a whole month
list.add(new ExportDateSegment(LocalDateTime.of(lastSegmentStartDate, segmentStartTime), end));
return list;
}
Here is another one using streams:
public class SplitDateRange {
public static class Range {
private final LocalDateTime start;
private final LocalDateTime end;
public Range(LocalDateTime start, LocalDateTime end) {
this.start = start;
this.end = end;
}
#Override
public String toString() {
return "Range{" + "start=" + start + ", end=" + end + '}';
}
}
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.parse("2020-01-10T13:00:25", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
LocalDateTime end = LocalDateTime.parse("2020-03-19T15:00:30", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
Stream.iterate(start, date -> date.isBefore(end), SplitDateRange::firstDateTimeOfNextMonth)
.map(date -> new Range(date, min(end, firstDateTimeOfNextMonth(date).minusSeconds(1))))
.collect(Collectors.toList())
.forEach(System.out::println);
}
public static LocalDateTime firstDateTimeOfNextMonth(LocalDateTime current) {
return current.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
}
public static LocalDateTime min(LocalDateTime a, LocalDateTime b) {
return a.isBefore(b) ? a : b;
}
}
please can any one help how to convert hexstring in the format "3676bb6c" in to date and time in the format "1-10-2013 11:47:44"
I tried for this but i am getting 12 hours time format but i need 24 hours format
the code would be like below
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class HexToDate {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//Print.logInfo("REV : " + revHexDate);
//String revHexDate="369E0Ec7";
String revHexDate="F52E32F8";
int decInt = hex2decimal(revHexDate);
System.out.println("11111 "+decInt);
int year = (decInt >> 26);
System.out.println("year is :"+year);
int month = (decInt >> 22) & 0x0f;
System.out.println("month is :"+month);
int date = (decInt >> 17) & 0x1f;
System.out.println("date is :"+date);
int hourOfDay = (decInt >> 12) & 0x1f;
int hrs=decInt/3600;
System.out.println("new hrsis "+hrs);
System.out.println("hourOfDay is :"+hourOfDay);
int minute = (decInt >> 6) & 0x3f;
System.out.println("minute is :"+minute);
int second = (decInt) & 0x3f;
System.out.println("second is :"+second);
Calendar calendar = Calendar.getInstance();
calendar.set(year, month-1, date, hourOfDay, minute, second);
//System.out.println(calendar.getTime());
SimpleDateFormat displayFormat1 = new SimpleDateFormat("ddMMYY",Locale.US);
String DDMMYY = displayFormat1.format(calendar.getTime());
System.out.println("DDMMYY is :"+DDMMYY);
SimpleDateFormat displayFormat2 = new SimpleDateFormat("hhmmss",Locale.US);
String HHMMSS = displayFormat2.format(calendar.getTime());
System.out.println("hhmmss is "+HHMMSS);
}
public static int hex2decimal(String s) {
String digits = "0123456789ABCDEF";
s = s.toUpperCase();
int val = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
int d = digits.indexOf(c);
val = 16*val + d;
}
return val;
}
}
use the following way to for converting hexstring to date
Date d=new Date(Long.parseLong("F52E32F8", 16));
System.out.println(d);
output
Tue Feb 17 20:07:25 IST 1970
Your problem is that you're using hh instead of HH to display hours. As stated here, the hh is used to display a 12-hour format.
Instead of using
SimpleDateFormat displayFormat2 = new SimpleDateFormat("hhmmss",Locale.US);
use
SimpleDateFormat displayFormat2 = new SimpleDateFormat("HHmmss",Locale.US);
Also, you didn't have to create your own method to convert hex to decimal, you could have used, among others
long decLong = Long.parseLong("F52E32F8", 16);
as javaBeginner stated.
I want to return an age in years as an int in a Java method.
What I have now is the following where getBirthDate() returns a Date object (with the birth date ;-)):
public int getAge() {
long ageInMillis = new Date().getTime() - getBirthDate().getTime();
Date age = new Date(ageInMillis);
return age.getYear();
}
But since getYear() is deprecated I'm wondering if there is a better way to do this? I'm not even sure this works correctly, since I have no unit tests in place (yet).
JDK 8 makes this easy and elegant:
public class AgeCalculator {
public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
if ((birthDate != null) && (currentDate != null)) {
return Period.between(birthDate, currentDate).getYears();
} else {
return 0;
}
}
}
A JUnit test to demonstrate its use:
public class AgeCalculatorTest {
#Test
public void testCalculateAge_Success() {
// setup
LocalDate birthDate = LocalDate.of(1961, 5, 17);
// exercise
int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
// assert
Assert.assertEquals(55, actual);
}
}
Everyone should be using JDK 8 by now. All earlier versions have passed the end of their support lives.
Check out Joda, which simplifies date/time calculations (Joda is also the basis of the new standard Java date/time apis, so you'll be learning a soon-to-be-standard API).
e.g.
LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);
which is as simple as you could want. The pre-Java 8 stuff is (as you've identified) somewhat unintuitive.
EDIT: Java 8 has something very similar and is worth checking out.
EDIT: This answer pre-dates the Java 8 date/time classes and is not current any more.
Modern answer and overview
a) Java-8 (java.time-package)
LocalDate start = LocalDate.of(1996, 2, 29);
LocalDate end = LocalDate.of(2014, 2, 28); // use for age-calculation: LocalDate.now()
long years = ChronoUnit.YEARS.between(start, end);
System.out.println(years); // 17
Note that the expression LocalDate.now() is implicitly related to the system timezone (which is often overlooked by users). For clarity it is generally better to use the overloaded method now(ZoneId.of("Europe/Paris")) specifying an explicit timezone (here "Europe/Paris" as example). If the system timezone is requested then my personal preference is to write LocalDate.now(ZoneId.systemDefault()) to make the relation to the system timezone clearer. This is more writing effort but makes reading easier.
b) Joda-Time
Please note that the proposed and accepted Joda-Time-solution yields a different computation result for the dates shown above (a rare case), namely:
LocalDate birthdate = new LocalDate(1996, 2, 29);
LocalDate now = new LocalDate(2014, 2, 28); // test, in real world without args
Years age = Years.yearsBetween(birthdate, now);
System.out.println(age.getYears()); // 18
I consider this as a small bug but the Joda-team has a different view on this weird behaviour and does not want to fix it (weird because the day-of-month of end date is smaller than of start date so the year should be one less). See also this closed issue.
c) java.util.Calendar etc.
For comparison see the various other answers. I would not recommend using these outdated classes at all because the resulting code is still errorprone in some exotic cases and/or way too complex considering the fact that the original question sounds so simple. In year 2015 we have really better libraries.
d) About Date4J:
The proposed solution is simple but will sometimes fail in case of leap years. Just evaluating the day of year is not reliable.
e) My own library Time4J:
This works similar to Java-8-solution. Just replace LocalDate by PlainDate and ChronoUnit.YEARS by CalendarUnit.YEARS. However, getting "today" requires an explicit timezone reference.
PlainDate start = PlainDate.of(1996, 2, 29);
PlainDate end = PlainDate.of(2014, 2, 28);
// use for age-calculation (today):
// => end = SystemClock.inZonalView(EUROPE.PARIS).today();
// or in system timezone: end = SystemClock.inLocalView().today();
long years = CalendarUnit.YEARS.between(start, end);
System.out.println(years); // 17
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = now.get(Calendar.DAY_OF_MONTH);
int day2 = dob.get(Calendar.DAY_OF_MONTH);
if (day2 > day1) {
age--;
}
}
// age is now correct
/**
* This Method is unit tested properly for very different cases ,
* taking care of Leap Year days difference in a year,
* and date cases month and Year boundary cases (12/31/1980, 01/01/1980 etc)
**/
public static int getAge(Date dateOfBirth) {
Calendar today = Calendar.getInstance();
Calendar birthDate = Calendar.getInstance();
int age = 0;
birthDate.setTime(dateOfBirth);
if (birthDate.after(today)) {
throw new IllegalArgumentException("Can't be born in the future");
}
age = today.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);
// If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year
if ( (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3) ||
(birthDate.get(Calendar.MONTH) > today.get(Calendar.MONTH ))){
age--;
// If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
}else if ((birthDate.get(Calendar.MONTH) == today.get(Calendar.MONTH )) &&
(birthDate.get(Calendar.DAY_OF_MONTH) > today.get(Calendar.DAY_OF_MONTH ))){
age--;
}
return age;
}
I simply use the milliseconds in a year constant value to my advantage:
Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);
If you are using GWT you will be limited to using java.util.Date, here is a method that takes the date as integers, but still uses java.util.Date:
public int getAge(int year, int month, int day) {
Date now = new Date();
int nowMonth = now.getMonth()+1;
int nowYear = now.getYear()+1900;
int result = nowYear - year;
if (month > nowMonth) {
result--;
}
else if (month == nowMonth) {
int nowDay = now.getDate();
if (day > nowDay) {
result--;
}
}
return result;
}
It's perhaps surprising to note that you don't need to know how many days or months there are in a year or how many days are in those months, likewise, you don't need to know about leap years, leap seconds, or any of that stuff using this simple, 100% accurate method:
public static int age(Date birthday, Date date) {
DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
int d1 = Integer.parseInt(formatter.format(birthday));
int d2 = Integer.parseInt(formatter.format(date));
int age = (d2-d1)/10000;
return age;
}
With the date4j library :
int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
age = age - 1;
}
This is an improved version of the one above... considering that you want age to be an 'int'. because sometimes you don't want to fill your program with a bunch of libraries.
public int getAge(Date dateOfBirth) {
int age = 0;
Calendar born = Calendar.getInstance();
Calendar now = Calendar.getInstance();
if(dateOfBirth!= null) {
now.setTime(new Date());
born.setTime(dateOfBirth);
if(born.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
if(now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR)) {
age-=1;
}
}
return age;
}
The correct answer using JodaTime is:
public int getAge() {
Years years = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate());
return years.getYears();
}
You could even shorten it into one line if you like. I copied the idea from BrianAgnew's answer, but I believe this is more correct as you see from the comments there (and it answers the question exactly).
Try to copy this one in your code, then use the method to get the age.
public static int getAge(Date birthday)
{
GregorianCalendar today = new GregorianCalendar();
GregorianCalendar bday = new GregorianCalendar();
GregorianCalendar bdayThisYear = new GregorianCalendar();
bday.setTime(birthday);
bdayThisYear.setTime(birthday);
bdayThisYear.set(Calendar.YEAR, today.get(Calendar.YEAR));
int age = today.get(Calendar.YEAR) - bday.get(Calendar.YEAR);
if(today.getTimeInMillis() < bdayThisYear.getTimeInMillis())
age--;
return age;
}
I use this piece of code for age calculation ,Hope this helps ..no libraries used
private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
public static int calculateAge(String date) {
int age = 0;
try {
Date date1 = dateFormat.parse(date);
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(date1);
if (dob.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = now.get(Calendar.DAY_OF_MONTH);
int day2 = dob.get(Calendar.DAY_OF_MONTH);
if (day2 > day1) {
age--;
}
}
} catch (ParseException e) {
e.printStackTrace();
}
return age ;
}
The fields birth and effect are both date fields:
Calendar bir = Calendar.getInstance();
bir.setTime(birth);
int birthNm = bir.get(Calendar.DAY_OF_YEAR);
int birthYear = bir.get(Calendar.YEAR);
Calendar eff = Calendar.getInstance();
eff.setTime(effect);
This basically a modification of John O's solution without using depreciated methods. I spent a fair amount of time trying to get his code to work in in my code. Maybe this will save others that time.
What about this one?
public Integer calculateAge(Date date) {
if (date == null) {
return null;
}
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date);
Calendar cal2 = Calendar.getInstance();
int i = 0;
while (cal1.before(cal2)) {
cal1.add(Calendar.YEAR, 1);
i += 1;
}
return i;
}
String dateofbirth has the date of birth. and format is whatever (defined in the following line):
org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern("mm/dd/yyyy");
Here is how to format:
org.joda.time.DateTime birthdateDate = formatter.parseDateTime(dateofbirth );
org.joda.time.DateMidnight birthdate = new org.joda.time.DateMidnight(birthdateDate.getYear(), birthdateDate.getMonthOfYear(), birthdateDate.getDayOfMonth() );
org.joda.time.DateTime now = new org.joda.time.DateTime();
org.joda.time.Years age = org.joda.time.Years.yearsBetween(birthdate, now);
java.lang.String ageStr = java.lang.String.valueOf (age.getYears());
Variable ageStr will have the years.
Elegant, seemingly correct, timestamp difference based variant of Yaron Ronen solution.
I am including a unit test to prove when and why it is not correct. It is impossible due (to possibly) different number of leap days (and seconds) in any timestamp difference. The discrepancy should be max +-1 day (and one second) for this algorithm, see test2(), whereas Yaron Ronen solution based on completely constant assumption of timeDiff / MILLI_SECONDS_YEAR can differ 10 days for a 40ty year old, nevertheless this variant is incorrect too.
It is tricky, because this improved variant, using formula diffAsCalendar.get(Calendar.YEAR) - 1970, returns correct results most of the time, as number of leap years in on average same between two dates.
/**
* Compute person's age based on timestamp difference between birth date and given date
* and prove it is INCORRECT approach.
*/
public class AgeUsingTimestamps {
public int getAge(Date today, Date dateOfBirth) {
long diffAsLong = today.getTime() - dateOfBirth.getTime();
Calendar diffAsCalendar = Calendar.getInstance();
diffAsCalendar.setTimeInMillis(diffAsLong);
return diffAsCalendar.get(Calendar.YEAR) - 1970; // base time where timestamp=0, precisely 1/1/1970 00:00:00
}
final static DateFormat df = new SimpleDateFormat("dd.MM.yyy HH:mm:ss");
#Test
public void test1() throws Exception {
Date dateOfBirth = df.parse("10.1.2000 00:00:00");
assertEquals(87, getAge(df.parse("08.1.2088 23:59:59"), dateOfBirth));
assertEquals(87, getAge(df.parse("09.1.2088 23:59:59"), dateOfBirth));
assertEquals(88, getAge(df.parse("10.1.2088 00:00:01"), dateOfBirth));
}
#Test
public void test2() throws Exception {
// between 2000 and 2021 was 6 leap days
// but between 1970 (base time) and 1991 there was only 5 leap days
// therefore age is switched one day earlier
// See http://www.onlineconversion.com/leapyear.htm
Date dateOfBirth = df.parse("10.1.2000 00:00:00");
assertEquals(20, getAge(df.parse("08.1.2021 23:59:59"), dateOfBirth));
assertEquals(20, getAge(df.parse("09.1.2021 23:59:59"), dateOfBirth)); // ERROR! returns incorrect age=21 here
assertEquals(21, getAge(df.parse("10.1.2021 00:00:01"), dateOfBirth));
}
}
public class CalculateAge {
private int age;
private void setAge(int age){
this.age=age;
}
public void calculateAge(Date date){
Calendar calendar=Calendar.getInstance();
Calendar calendarnow=Calendar.getInstance();
calendarnow.getTimeZone();
calendar.setTime(date);
int getmonth= calendar.get(calendar.MONTH);
int getyears= calendar.get(calendar.YEAR);
int currentmonth= calendarnow.get(calendarnow.MONTH);
int currentyear= calendarnow.get(calendarnow.YEAR);
int age = ((currentyear*12+currentmonth)-(getyears*12+getmonth))/12;
setAge(age);
}
public int getAge(){
return this.age;
}
/**
* Compute from string date in the format of yyyy-MM-dd HH:mm:ss the age of a person.
* #author Yaron Ronen
* #date 04/06/2012
*/
private int computeAge(String sDate)
{
// Initial variables.
Date dbDate = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Parse sDate.
try
{
dbDate = (Date)dateFormat.parse(sDate);
}
catch(ParseException e)
{
Log.e("MyApplication","Can not compute age from date:"+sDate,e);
return ILLEGAL_DATE; // Const = -2
}
// Compute age.
long timeDiff = System.currentTimeMillis() - dbDate.getTime();
int age = (int)(timeDiff / MILLI_SECONDS_YEAR); // MILLI_SECONDS_YEAR = 31558464000L;
return age;
}
Here is the java code to calculate age in year, month and days.
public static AgeModel calculateAge(long birthDate) {
int years = 0;
int months = 0;
int days = 0;
if (birthDate != 0) {
//create calendar object for birth day
Calendar birthDay = Calendar.getInstance();
birthDay.setTimeInMillis(birthDate);
//create calendar object for current day
Calendar now = Calendar.getInstance();
Calendar current = Calendar.getInstance();
//Get difference between years
years = now.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);
//get months
int currMonth = now.get(Calendar.MONTH) + 1;
int birthMonth = birthDay.get(Calendar.MONTH) + 1;
//Get difference between months
months = currMonth - birthMonth;
//if month difference is in negative then reduce years by one and calculate the number of months.
if (months < 0) {
years--;
months = 12 - birthMonth + currMonth;
} else if (months == 0 && now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
years--;
months = 11;
}
//Calculate the days
if (now.get(Calendar.DATE) > birthDay.get(Calendar.DATE))
days = now.get(Calendar.DATE) - birthDay.get(Calendar.DATE);
else if (now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
int today = now.get(Calendar.DAY_OF_MONTH);
now.add(Calendar.MONTH, -1);
days = now.getActualMaximum(Calendar.DAY_OF_MONTH) - birthDay.get(Calendar.DAY_OF_MONTH) + today;
} else {
days = 0;
if (months == 12) {
years++;
months = 0;
}
}
}
//Create new Age object
return new AgeModel(days, months, years);
}
Easiest way without any libraries:
long today = new Date().getTime();
long diff = today - birth;
long age = diff / DateUtils.YEAR_IN_MILLIS;
With Java 8, we can calculate a person age with one line of code:
public int calCAge(int year, int month,int days){
return LocalDate.now().minus(Period.of(year, month, days)).getYear();
}
Simple solution in kotlin.
fun getAgeOfUser(date: String?) : Int {
if(date.isNullOrEmpty()) return 0
val calendar = Calendar.getInstance()
val cYear = calendar.get(Calendar.YEAR)
val cDay = calendar.get(Calendar.DAY_OF_YEAR)
val dob = Calendar.getInstance()
dob.timeInMillis = date.toLong()
val bYear = dob.get(Calendar.YEAR)
val bDay = dob.get(Calendar.DAY_OF_YEAR)
var age = cYear - bYear
if(cDay < bDay) age--
return age
}
public int getAge(Date dateOfBirth)
{
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(dateOfBirth);
if (dob.after(now))
{
throw new IllegalArgumentException("Can't be born in the future");
}
int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR))
{
age--;
}
return age;
}
import java.io.*;
class AgeCalculator
{
public static void main(String args[])
{
InputStreamReader ins=new InputStreamReader(System.in);
BufferedReader hey=new BufferedReader(ins);
try
{
System.out.println("Please enter your name: ");
String name=hey.readLine();
System.out.println("Please enter your birth date: ");
String date=hey.readLine();
System.out.println("please enter your birth month:");
String month=hey.readLine();
System.out.println("please enter your birth year:");
String year=hey.readLine();
System.out.println("please enter current year:");
String cYear=hey.readLine();
int bDate = Integer.parseInt(date);
int bMonth = Integer.parseInt(month);
int bYear = Integer.parseInt(year);
int ccYear=Integer.parseInt(cYear);
int age;
age = ccYear-bYear;
int totalMonth=12;
int yourMonth=totalMonth-bMonth;
System.out.println(" Hi " + name + " your are " + age + " years " + yourMonth + " months old ");
}
catch(IOException err)
{
System.out.println("");
}
}
}
public int getAge(String birthdate, String today){
// birthdate = "1986-02-22"
// today = "2014-09-16"
// String class has a split method for splitting a string
// split(<delimiter>)
// birth[0] = 1986 as string
// birth[1] = 02 as string
// birth[2] = 22 as string
// now[0] = 2014 as string
// now[1] = 09 as string
// now[2] = 16 as string
// **birth** and **now** arrays are automatically contains 3 elements
// split method here returns 3 elements because of yyyy-MM-dd value
String birth[] = birthdate.split("-");
String now[] = today.split("-");
int age = 0;
// let us convert string values into integer values
// with the use of Integer.parseInt(<string>)
int ybirth = Integer.parseInt(birth[0]);
int mbirth = Integer.parseInt(birth[1]);
int dbirth = Integer.parseInt(birth[2]);
int ynow = Integer.parseInt(now[0]);
int mnow = Integer.parseInt(now[1]);
int dnow = Integer.parseInt(now[2]);
if(ybirth < ynow){ // has age if birth year is lesser than current year
age = ynow - ybirth; // let us get the interval of birth year and current year
if(mbirth == mnow){ // when birth month comes, it's ok to have age = ynow - ybirth if
if(dbirth > dnow) // birth day is coming. need to subtract 1 from age. not yet a bday
age--;
}else if(mbirth > mnow){ age--; } // birth month is comming. need to subtract 1 from age
}
return age;
}
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.Period;
public class AgeCalculator1 {
public static void main(String args[]) {
LocalDate start = LocalDate.of(1970, 2, 23);
LocalDate end = LocalDate.now(ZoneId.systemDefault());
Period p = Period.between(start, end);
//The output of the program is :
//45 years 6 months and 6 days.
System.out.print(p.getYears() + " year" + (p.getYears() > 1 ? "s " : " ") );
System.out.print(p.getMonths() + " month" + (p.getMonths() > 1 ? "s and " : " and ") );
System.out.print(p.getDays() + " day" + (p.getDays() > 1 ? "s.\n" : ".\n") );
}//method main ends here.
}
I appreciate all correct answers but this is the kotlin answer for the same question
I hope would be helpful to kotlin developers
fun calculateAge(birthDate: Date): Int {
val now = Date()
val timeBetween = now.getTime() - birthDate.getTime();
val yearsBetween = timeBetween / 3.15576e+10;
return Math.floor(yearsBetween).toInt()
}