-2

I have a birthdate in integers:

int year, month, day;

and a timestamp.

long timestamp;

I'm going to check if the birthdate is n years (for example 2 years) younger than my timestamp. How can I do it?

The minimum API level is 15.

Alireza Noorali
  • 3,129
  • 2
  • 33
  • 80

3 Answers3

2

tl;dr

Instant                               // `Instant` = moment in UTC. Resolved in nanoseconds, much finer than the milliseconds seen in the Question.
.ofEpochMilli( 1_532_197_770_716L )   // Parse a count-from-epoch as an `Instant` object.
.atZone(                              // Adjust from UTC to a particular time zone.
    ZoneId.of( "America/Montreal" )   // Always use `Contintent/Region` formatted names, never the 3-4 letter pseudo-zones such as `PST` or `IST`.
)                                     // Returns a `ZonedDateTime` object. Think of it conceptually as: ZonedDateTime = ( Instant + ZoneId ). Represents the same moment, the same point on the timeline, but viewed through the lens of the wall-clock time used by the people of a particular region.
.toLocalDate()                        // Returns a `LocalDate`, date-only value without time-of-day and without time zone.
.minus(                               // Subtract a span-of-time.
    Period.ofYears( 2 )               // `Period` = a span of time unattached to the timeline, in granularity of a number of years-months-days.
)                                     // Returns another `LocalDate`. Using immutable objects pattern, producing a new object rather than altering (“mutating”) the original.
.isAfter(                             // Compare one `LocalDate` with another.
    LocalDate.of( yourYear , yourMonth , yourDay )
)                                     // Returns a boolean.

java.time

Parse your count of milliseconds since the epoch reference of first moment of 1970 in UTC as a Instant.

Instant instant = Instant.ofEpochMilli( millis ) ;

Adjust from UTC to the time zone in which you want to interpret a date. Understand that for any given moment, the date and time-of-day both vary around the globe by zone.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( “Pacific/Auckland” ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Extract only the date portion, without the time-of-day and without the time zone.

LocalDate ld = zdt.toLocalDate() ;

Move backwards in time by your desired amount of time.

Period p = Period.ofYears( 2 ) ;
LocalDate twoYearsPrior = ld.minus( p ) ;

Represent the birthday.

LocalDate birthday = LocalDate.of( y , m , d ) ;

Compare.

Boolean x = birthday.isBefore( twoYearsPrior ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

Try using joda time for lower versions.

private int checkDateDiff(long timestamp, int bdayYear, int bdayMonth, int bdayDay) {

    DateTime startDateTime = new DateTime(timestamp);

    DateTime endDateTime = new DateTime(bdayYear, bdayMonth, bdayDay, 0, 0);

    Period period = new Period(endDateTime, startDateTime);

    int yearsDiff = period.getYears();

    return yearsDiff;
}
Saheb
  • 21
  • 4
  • 2
    This is not gonna work as you are only checking years. You need to add months and days to the calculation aswell. As one date may start in January and one in December. – Ogiez Jul 21 '18 at 16:03
  • FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 21 '18 at 18:28
0

This might work for you. Make Calendar objects and check the difference in the ms time between them. Basically just converting the date you had in integers to ms instead.

    int year, month, day;
    long timestamp;
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month+1, day);


    long twoYears = 63113852000L; //Two years in ms

    //Check if the difference is more than 2 years.
    if(calendar.getTimeInMillis() - timestamp >= twoYears || calendar.getTimeInMillis() - timestamp <= -twoYears) {
         System.out.println("More than 2 years dif");
    }
Ogiez
  • 97
  • 6
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 21 '18 at 18:28